blob: b74554d63dbc633fca926c978de5a6df047c3b99 [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 {
1233 aspath = rule;
1234 binfo = object;
1235
1236 if (binfo->attr->aspath->refcnt)
1237 new = aspath_dup (binfo->attr->aspath);
1238 else
1239 new = binfo->attr->aspath;
1240
1241 aspath_prepend (aspath, new);
1242 binfo->attr->aspath = new;
1243 }
1244
1245 return RMAP_OKAY;
1246}
1247
Timo Teräs2aa640b2014-05-20 08:57:26 +03001248/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001249struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1250{
1251 "as-path prepend",
1252 route_set_aspath_prepend,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001253 route_aspath_compile,
1254 route_aspath_free,
paul718e3742002-12-13 20:15:29 +00001255};
David Lamparter6b0655a2014-06-04 06:53:35 +02001256
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001257/* `set as-path exclude ASn' */
1258
1259/* For ASN exclude mechanism.
1260 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1261 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1262 */
1263static route_map_result_t
1264route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1265{
1266 struct aspath * new_path, * exclude_path;
1267 struct bgp_info *binfo;
1268
1269 if (type == RMAP_BGP)
1270 {
1271 exclude_path = rule;
1272 binfo = object;
1273 if (binfo->attr->aspath->refcnt)
1274 new_path = aspath_dup (binfo->attr->aspath);
1275 else
1276 new_path = binfo->attr->aspath;
1277 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1278 }
1279 return RMAP_OKAY;
1280}
1281
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001282/* Set ASn exlude rule structure. */
1283struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1284{
1285 "as-path exclude",
1286 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001287 route_aspath_compile,
1288 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001289};
David Lamparter6b0655a2014-06-04 06:53:35 +02001290
paul718e3742002-12-13 20:15:29 +00001291/* `set community COMMUNITY' */
1292struct rmap_com_set
1293{
1294 struct community *com;
1295 int additive;
1296 int none;
1297};
1298
1299/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001300static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001301route_set_community (void *rule, struct prefix *prefix,
1302 route_map_object_t type, void *object)
1303{
1304 struct rmap_com_set *rcs;
1305 struct bgp_info *binfo;
1306 struct attr *attr;
1307 struct community *new = NULL;
1308 struct community *old;
1309 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001310
paul718e3742002-12-13 20:15:29 +00001311 if (type == RMAP_BGP)
1312 {
1313 rcs = rule;
1314 binfo = object;
1315 attr = binfo->attr;
1316 old = attr->community;
1317
1318 /* "none" case. */
1319 if (rcs->none)
1320 {
1321 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1322 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001323 /* See the longer comment down below. */
1324 if (old && old->refcnt == 0)
1325 community_free(old);
paul718e3742002-12-13 20:15:29 +00001326 return RMAP_OKAY;
1327 }
1328
1329 /* "additive" case. */
1330 if (rcs->additive && old)
1331 {
1332 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001333
1334 /* HACK: if the old community is not intern'd,
1335 * we should free it here, or all reference to it may be lost.
1336 * Really need to cleanup attribute caching sometime.
1337 */
1338 if (old->refcnt == 0)
1339 community_free (old);
paul718e3742002-12-13 20:15:29 +00001340 new = community_uniq_sort (merge);
1341 community_free (merge);
1342 }
1343 else
1344 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001345
1346 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001347 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001348
paul718e3742002-12-13 20:15:29 +00001349 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1350 }
1351
1352 return RMAP_OKAY;
1353}
1354
1355/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001356static void *
paulfd79ac92004-10-13 05:06:08 +00001357route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001358{
1359 struct rmap_com_set *rcs;
1360 struct community *com = NULL;
1361 char *sp;
1362 int additive = 0;
1363 int none = 0;
1364
1365 if (strcmp (arg, "none") == 0)
1366 none = 1;
1367 else
1368 {
1369 sp = strstr (arg, "additive");
1370
1371 if (sp && sp > arg)
1372 {
1373 /* "additive" keyworkd is included. */
1374 additive = 1;
1375 *(sp - 1) = '\0';
1376 }
1377
1378 com = community_str2com (arg);
1379
1380 if (additive)
1381 *(sp - 1) = ' ';
1382
1383 if (! com)
1384 return NULL;
1385 }
1386
Stephen Hemminger393deb92008-08-18 14:13:29 -07001387 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001388 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001389 rcs->additive = additive;
1390 rcs->none = none;
1391
1392 return rcs;
1393}
1394
1395/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001396static void
paul718e3742002-12-13 20:15:29 +00001397route_set_community_free (void *rule)
1398{
1399 struct rmap_com_set *rcs = rule;
1400
1401 if (rcs->com)
1402 community_free (rcs->com);
1403 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1404}
1405
1406/* Set community rule structure. */
1407struct route_map_rule_cmd route_set_community_cmd =
1408{
1409 "community",
1410 route_set_community,
1411 route_set_community_compile,
1412 route_set_community_free,
1413};
David Lamparter6b0655a2014-06-04 06:53:35 +02001414
hassofee6e4e2005-02-02 16:29:31 +00001415/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001416
1417/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001418static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001419route_set_community_delete (void *rule, struct prefix *prefix,
1420 route_map_object_t type, void *object)
1421{
1422 struct community_list *list;
1423 struct community *merge;
1424 struct community *new;
1425 struct community *old;
1426 struct bgp_info *binfo;
1427
1428 if (type == RMAP_BGP)
1429 {
1430 if (! rule)
1431 return RMAP_OKAY;
1432
1433 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001434 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001435 old = binfo->attr->community;
1436
1437 if (list && old)
1438 {
1439 merge = community_list_match_delete (community_dup (old), list);
1440 new = community_uniq_sort (merge);
1441 community_free (merge);
1442
Michael Lambert604a9b42010-09-13 11:48:11 -04001443 /* HACK: if the old community is not intern'd,
1444 * we should free it here, or all reference to it may be lost.
1445 * Really need to cleanup attribute caching sometime.
1446 */
1447 if (old->refcnt == 0)
1448 community_free (old);
1449
paul718e3742002-12-13 20:15:29 +00001450 if (new->size == 0)
1451 {
1452 binfo->attr->community = NULL;
1453 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1454 community_free (new);
1455 }
1456 else
1457 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001458 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001459 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1460 }
1461 }
1462 }
1463
1464 return RMAP_OKAY;
1465}
1466
1467/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001468static void *
paulfd79ac92004-10-13 05:06:08 +00001469route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001470{
1471 char *p;
1472 char *str;
1473 int len;
1474
1475 p = strchr (arg, ' ');
1476 if (p)
1477 {
1478 len = p - arg;
1479 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1480 memcpy (str, arg, len);
1481 }
1482 else
1483 str = NULL;
1484
1485 return str;
1486}
1487
1488/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001489static void
paul718e3742002-12-13 20:15:29 +00001490route_set_community_delete_free (void *rule)
1491{
1492 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1493}
1494
1495/* Set community rule structure. */
1496struct route_map_rule_cmd route_set_community_delete_cmd =
1497{
1498 "comm-list",
1499 route_set_community_delete,
1500 route_set_community_delete_compile,
1501 route_set_community_delete_free,
1502};
David Lamparter6b0655a2014-06-04 06:53:35 +02001503
paul718e3742002-12-13 20:15:29 +00001504/* `set extcommunity rt COMMUNITY' */
1505
David Lamparter73d78ea2014-06-04 00:58:47 +02001506/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001507static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001508route_set_ecommunity (void *rule, struct prefix *prefix,
1509 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001510{
1511 struct ecommunity *ecom;
1512 struct ecommunity *new_ecom;
1513 struct ecommunity *old_ecom;
1514 struct bgp_info *bgp_info;
1515
1516 if (type == RMAP_BGP)
1517 {
1518 ecom = rule;
1519 bgp_info = object;
1520
1521 if (! ecom)
1522 return RMAP_OKAY;
1523
1524 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001525 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001526
1527 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001528 {
1529 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1530
1531 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1532 * ->refcnt = 0 => set by a previous route-map statement */
1533 if (!old_ecom->refcnt)
1534 ecommunity_free (&old_ecom);
1535 }
paul718e3742002-12-13 20:15:29 +00001536 else
1537 new_ecom = ecommunity_dup (ecom);
1538
David Lamparter27bf90a2014-06-04 00:59:01 +02001539 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1540 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001541
paul718e3742002-12-13 20:15:29 +00001542 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1543 }
1544 return RMAP_OKAY;
1545}
1546
1547/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001548static void *
paulfd79ac92004-10-13 05:06:08 +00001549route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001550{
1551 struct ecommunity *ecom;
1552
1553 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1554 if (! ecom)
1555 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001556 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001557}
1558
David Lamparter73d78ea2014-06-04 00:58:47 +02001559/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001560static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001561route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001562{
1563 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001564 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001565}
1566
1567/* Set community rule structure. */
1568struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1569{
1570 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001571 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001572 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001573 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001574};
1575
1576/* `set extcommunity soo COMMUNITY' */
1577
paul718e3742002-12-13 20:15:29 +00001578/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001579static void *
paulfd79ac92004-10-13 05:06:08 +00001580route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001581{
1582 struct ecommunity *ecom;
1583
1584 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1585 if (! ecom)
1586 return NULL;
1587
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001588 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001589}
1590
paul718e3742002-12-13 20:15:29 +00001591/* Set community rule structure. */
1592struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1593{
1594 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001595 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001596 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001597 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001598};
David Lamparter6b0655a2014-06-04 06:53:35 +02001599
paul718e3742002-12-13 20:15:29 +00001600/* `set origin ORIGIN' */
1601
1602/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001603static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001604route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1605{
1606 u_char *origin;
1607 struct bgp_info *bgp_info;
1608
1609 if (type == RMAP_BGP)
1610 {
1611 origin = rule;
1612 bgp_info = object;
1613
1614 bgp_info->attr->origin = *origin;
1615 }
1616
1617 return RMAP_OKAY;
1618}
1619
1620/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001621static void *
paulfd79ac92004-10-13 05:06:08 +00001622route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001623{
1624 u_char *origin;
1625
1626 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1627
1628 if (strcmp (arg, "igp") == 0)
1629 *origin = 0;
1630 else if (strcmp (arg, "egp") == 0)
1631 *origin = 1;
1632 else
1633 *origin = 2;
1634
1635 return origin;
1636}
1637
1638/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001639static void
paul718e3742002-12-13 20:15:29 +00001640route_set_origin_free (void *rule)
1641{
1642 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1643}
1644
Timo Teräs2aa640b2014-05-20 08:57:26 +03001645/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001646struct route_map_rule_cmd route_set_origin_cmd =
1647{
1648 "origin",
1649 route_set_origin,
1650 route_set_origin_compile,
1651 route_set_origin_free,
1652};
David Lamparter6b0655a2014-06-04 06:53:35 +02001653
paul718e3742002-12-13 20:15:29 +00001654/* `set atomic-aggregate' */
1655
1656/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001657static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001658route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1659 route_map_object_t type, void *object)
1660{
1661 struct bgp_info *bgp_info;
1662
1663 if (type == RMAP_BGP)
1664 {
1665 bgp_info = object;
1666 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1667 }
1668
1669 return RMAP_OKAY;
1670}
1671
1672/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001673static void *
paulfd79ac92004-10-13 05:06:08 +00001674route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001675{
1676 return (void *)1;
1677}
1678
1679/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001680static void
paul718e3742002-12-13 20:15:29 +00001681route_set_atomic_aggregate_free (void *rule)
1682{
1683 return;
1684}
1685
1686/* Set atomic aggregate rule structure. */
1687struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1688{
1689 "atomic-aggregate",
1690 route_set_atomic_aggregate,
1691 route_set_atomic_aggregate_compile,
1692 route_set_atomic_aggregate_free,
1693};
David Lamparter6b0655a2014-06-04 06:53:35 +02001694
paul718e3742002-12-13 20:15:29 +00001695/* `set aggregator as AS A.B.C.D' */
1696struct aggregator
1697{
1698 as_t as;
1699 struct in_addr address;
1700};
1701
paul94f2b392005-06-28 12:44:16 +00001702static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001703route_set_aggregator_as (void *rule, struct prefix *prefix,
1704 route_map_object_t type, void *object)
1705{
1706 struct bgp_info *bgp_info;
1707 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001708 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001709
1710 if (type == RMAP_BGP)
1711 {
1712 bgp_info = object;
1713 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001714 ae = bgp_attr_extra_get (bgp_info->attr);
1715
1716 ae->aggregator_as = aggregator->as;
1717 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001718 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1719 }
1720
1721 return RMAP_OKAY;
1722}
1723
paul94f2b392005-06-28 12:44:16 +00001724static void *
paulfd79ac92004-10-13 05:06:08 +00001725route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001726{
1727 struct aggregator *aggregator;
1728 char as[10];
1729 char address[20];
1730
Stephen Hemminger393deb92008-08-18 14:13:29 -07001731 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001732 sscanf (arg, "%s %s", as, address);
1733
1734 aggregator->as = strtoul (as, NULL, 10);
1735 inet_aton (address, &aggregator->address);
1736
1737 return aggregator;
1738}
1739
paul94f2b392005-06-28 12:44:16 +00001740static void
paul718e3742002-12-13 20:15:29 +00001741route_set_aggregator_as_free (void *rule)
1742{
1743 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1744}
1745
1746struct route_map_rule_cmd route_set_aggregator_as_cmd =
1747{
1748 "aggregator as",
1749 route_set_aggregator_as,
1750 route_set_aggregator_as_compile,
1751 route_set_aggregator_as_free,
1752};
David Lamparter6b0655a2014-06-04 06:53:35 +02001753
paul718e3742002-12-13 20:15:29 +00001754#ifdef HAVE_IPV6
1755/* `match ipv6 address IP_ACCESS_LIST' */
1756
paul94f2b392005-06-28 12:44:16 +00001757static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001758route_match_ipv6_address (void *rule, struct prefix *prefix,
1759 route_map_object_t type, void *object)
1760{
1761 struct access_list *alist;
1762
1763 if (type == RMAP_BGP)
1764 {
1765 alist = access_list_lookup (AFI_IP6, (char *) rule);
1766 if (alist == NULL)
1767 return RMAP_NOMATCH;
1768
1769 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1770 RMAP_NOMATCH : RMAP_MATCH);
1771 }
1772 return RMAP_NOMATCH;
1773}
1774
paul94f2b392005-06-28 12:44:16 +00001775static void *
paulfd79ac92004-10-13 05:06:08 +00001776route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001777{
1778 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1779}
1780
paul94f2b392005-06-28 12:44:16 +00001781static void
paul718e3742002-12-13 20:15:29 +00001782route_match_ipv6_address_free (void *rule)
1783{
1784 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1785}
1786
1787/* Route map commands for ip address matching. */
1788struct route_map_rule_cmd route_match_ipv6_address_cmd =
1789{
1790 "ipv6 address",
1791 route_match_ipv6_address,
1792 route_match_ipv6_address_compile,
1793 route_match_ipv6_address_free
1794};
David Lamparter6b0655a2014-06-04 06:53:35 +02001795
paul718e3742002-12-13 20:15:29 +00001796/* `match ipv6 next-hop IP_ADDRESS' */
1797
paul94f2b392005-06-28 12:44:16 +00001798static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001799route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1800 route_map_object_t type, void *object)
1801{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001802 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001803 struct bgp_info *bgp_info;
1804
1805 if (type == RMAP_BGP)
1806 {
paul718e3742002-12-13 20:15:29 +00001807 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001808
1809 if (!bgp_info->attr->extra)
1810 return RMAP_NOMATCH;
1811
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001812 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001813 return RMAP_MATCH;
1814
Paul Jakmafb982c22007-05-04 20:15:47 +00001815 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001816 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001817 return RMAP_MATCH;
1818
1819 return RMAP_NOMATCH;
1820 }
1821
1822 return RMAP_NOMATCH;
1823}
1824
paul94f2b392005-06-28 12:44:16 +00001825static void *
paulfd79ac92004-10-13 05:06:08 +00001826route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001827{
1828 struct in6_addr *address;
1829 int ret;
1830
1831 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1832
1833 ret = inet_pton (AF_INET6, arg, address);
1834 if (!ret)
1835 {
1836 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1837 return NULL;
1838 }
1839
1840 return address;
1841}
1842
paul94f2b392005-06-28 12:44:16 +00001843static void
paul718e3742002-12-13 20:15:29 +00001844route_match_ipv6_next_hop_free (void *rule)
1845{
1846 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1847}
1848
1849struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1850{
1851 "ipv6 next-hop",
1852 route_match_ipv6_next_hop,
1853 route_match_ipv6_next_hop_compile,
1854 route_match_ipv6_next_hop_free
1855};
David Lamparter6b0655a2014-06-04 06:53:35 +02001856
paul718e3742002-12-13 20:15:29 +00001857/* `match ipv6 address prefix-list PREFIX_LIST' */
1858
paul94f2b392005-06-28 12:44:16 +00001859static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001860route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1861 route_map_object_t type, void *object)
1862{
1863 struct prefix_list *plist;
1864
1865 if (type == RMAP_BGP)
1866 {
1867 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1868 if (plist == NULL)
1869 return RMAP_NOMATCH;
1870
1871 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1872 RMAP_NOMATCH : RMAP_MATCH);
1873 }
1874 return RMAP_NOMATCH;
1875}
1876
paul94f2b392005-06-28 12:44:16 +00001877static void *
paulfd79ac92004-10-13 05:06:08 +00001878route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001879{
1880 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1881}
1882
paul94f2b392005-06-28 12:44:16 +00001883static void
paul718e3742002-12-13 20:15:29 +00001884route_match_ipv6_address_prefix_list_free (void *rule)
1885{
1886 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1887}
1888
1889struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1890{
1891 "ipv6 address prefix-list",
1892 route_match_ipv6_address_prefix_list,
1893 route_match_ipv6_address_prefix_list_compile,
1894 route_match_ipv6_address_prefix_list_free
1895};
David Lamparter6b0655a2014-06-04 06:53:35 +02001896
paul718e3742002-12-13 20:15:29 +00001897/* `set ipv6 nexthop global IP_ADDRESS' */
1898
1899/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001900static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001901route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1902 route_map_object_t type, void *object)
1903{
1904 struct in6_addr *address;
1905 struct bgp_info *bgp_info;
1906
1907 if (type == RMAP_BGP)
1908 {
1909 /* Fetch routemap's rule information. */
1910 address = rule;
1911 bgp_info = object;
1912
1913 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001914 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001915
1916 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001917 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1918 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001919 }
1920
1921 return RMAP_OKAY;
1922}
1923
1924/* Route map `ip next-hop' compile function. Given string is converted
1925 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001926static void *
paulfd79ac92004-10-13 05:06:08 +00001927route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001928{
1929 int ret;
1930 struct in6_addr *address;
1931
1932 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1933
1934 ret = inet_pton (AF_INET6, arg, address);
1935
1936 if (ret == 0)
1937 {
1938 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1939 return NULL;
1940 }
1941
1942 return address;
1943}
1944
1945/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001946static void
paul718e3742002-12-13 20:15:29 +00001947route_set_ipv6_nexthop_global_free (void *rule)
1948{
1949 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1950}
1951
1952/* Route map commands for ip nexthop set. */
1953struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1954{
1955 "ipv6 next-hop global",
1956 route_set_ipv6_nexthop_global,
1957 route_set_ipv6_nexthop_global_compile,
1958 route_set_ipv6_nexthop_global_free
1959};
David Lamparter6b0655a2014-06-04 06:53:35 +02001960
paul718e3742002-12-13 20:15:29 +00001961/* `set ipv6 nexthop local IP_ADDRESS' */
1962
1963/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001964static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001965route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1966 route_map_object_t type, void *object)
1967{
1968 struct in6_addr *address;
1969 struct bgp_info *bgp_info;
1970
1971 if (type == RMAP_BGP)
1972 {
1973 /* Fetch routemap's rule information. */
1974 address = rule;
1975 bgp_info = object;
1976
1977 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001978 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001979
1980 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001981 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1982 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001983 }
1984
1985 return RMAP_OKAY;
1986}
1987
1988/* Route map `ip nexthop' compile function. Given string is converted
1989 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001990static void *
paulfd79ac92004-10-13 05:06:08 +00001991route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001992{
1993 int ret;
1994 struct in6_addr *address;
1995
1996 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1997
1998 ret = inet_pton (AF_INET6, arg, address);
1999
2000 if (ret == 0)
2001 {
2002 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2003 return NULL;
2004 }
2005
2006 return address;
2007}
2008
2009/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002010static void
paul718e3742002-12-13 20:15:29 +00002011route_set_ipv6_nexthop_local_free (void *rule)
2012{
2013 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2014}
2015
2016/* Route map commands for ip nexthop set. */
2017struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2018{
2019 "ipv6 next-hop local",
2020 route_set_ipv6_nexthop_local,
2021 route_set_ipv6_nexthop_local_compile,
2022 route_set_ipv6_nexthop_local_free
2023};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002024
2025/* `set ipv6 nexthop peer-address' */
2026
2027/* Set nexthop to object. ojbect must be pointer to struct attr. */
2028static route_map_result_t
2029route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2030 route_map_object_t type, void *object)
2031{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002032 struct in6_addr peer_address;
2033 struct bgp_info *bgp_info;
2034 struct peer *peer;
2035 char peer_addr_buf[INET6_ADDRSTRLEN];
2036
2037 if (type == RMAP_BGP)
2038 {
2039 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002040 bgp_info = object;
2041 peer = bgp_info->peer;
2042
2043 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2044 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2045 && peer->su_remote
2046 && sockunion_family (peer->su_remote) == AF_INET6)
2047 {
2048 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
2049 peer_addr_buf,
2050 INET6_ADDRSTRLEN),
2051 &peer_address);
2052 }
2053 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2054 && peer->su_local
2055 && sockunion_family (peer->su_local) == AF_INET6)
2056 {
2057 inet_pton (AF_INET, sockunion2str (peer->su_local,
2058 peer_addr_buf,
2059 INET6_ADDRSTRLEN),
2060 &peer_address);
2061 }
2062
2063 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2064 {
2065 /* Set next hop value. */
2066 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2067
2068 /* Set nexthop length. */
2069 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2070 bgp_info->attr->extra->mp_nexthop_len = 32;
2071 }
2072 else
2073 {
2074 /* Set next hop value. */
2075 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2076
2077 /* Set nexthop length. */
2078 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2079 bgp_info->attr->extra->mp_nexthop_len = 16;
2080 }
2081 }
2082
2083 return RMAP_OKAY;
2084}
2085
2086/* Route map `ip next-hop' compile function. Given string is converted
2087 to struct in_addr structure. */
2088static void *
2089route_set_ipv6_nexthop_peer_compile (const char *arg)
2090{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002091 int *rins = NULL;
2092
2093 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2094 *rins = 1;
2095
2096 return rins;
2097}
2098
2099/* Free route map's compiled `ip next-hop' value. */
2100static void
2101route_set_ipv6_nexthop_peer_free (void *rule)
2102{
2103 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2104}
2105
2106/* Route map commands for ip nexthop set. */
2107struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2108{
2109 "ipv6 next-hop peer-address",
2110 route_set_ipv6_nexthop_peer,
2111 route_set_ipv6_nexthop_peer_compile,
2112 route_set_ipv6_nexthop_peer_free
2113};
2114
paul718e3742002-12-13 20:15:29 +00002115#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02002116
paul718e3742002-12-13 20:15:29 +00002117/* `set vpnv4 nexthop A.B.C.D' */
2118
paul94f2b392005-06-28 12:44:16 +00002119static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002120route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2121 route_map_object_t type, void *object)
2122{
2123 struct in_addr *address;
2124 struct bgp_info *bgp_info;
2125
2126 if (type == RMAP_BGP)
2127 {
2128 /* Fetch routemap's rule information. */
2129 address = rule;
2130 bgp_info = object;
2131
2132 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002133 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002134 }
2135
2136 return RMAP_OKAY;
2137}
2138
paul94f2b392005-06-28 12:44:16 +00002139static void *
paulfd79ac92004-10-13 05:06:08 +00002140route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002141{
2142 int ret;
2143 struct in_addr *address;
2144
2145 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2146
2147 ret = inet_aton (arg, address);
2148
2149 if (ret == 0)
2150 {
2151 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2152 return NULL;
2153 }
2154
2155 return address;
2156}
2157
paul94f2b392005-06-28 12:44:16 +00002158static void
paul718e3742002-12-13 20:15:29 +00002159route_set_vpnv4_nexthop_free (void *rule)
2160{
2161 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2162}
2163
2164/* Route map commands for ip nexthop set. */
2165struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2166{
2167 "vpnv4 next-hop",
2168 route_set_vpnv4_nexthop,
2169 route_set_vpnv4_nexthop_compile,
2170 route_set_vpnv4_nexthop_free
2171};
David Lamparter6b0655a2014-06-04 06:53:35 +02002172
paul718e3742002-12-13 20:15:29 +00002173/* `set originator-id' */
2174
2175/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002176static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002177route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2178{
2179 struct in_addr *address;
2180 struct bgp_info *bgp_info;
2181
2182 if (type == RMAP_BGP)
2183 {
2184 address = rule;
2185 bgp_info = object;
2186
2187 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002188 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002189 }
2190
2191 return RMAP_OKAY;
2192}
2193
2194/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002195static void *
paulfd79ac92004-10-13 05:06:08 +00002196route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002197{
2198 int ret;
2199 struct in_addr *address;
2200
2201 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2202
2203 ret = inet_aton (arg, address);
2204
2205 if (ret == 0)
2206 {
2207 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2208 return NULL;
2209 }
2210
2211 return address;
2212}
2213
2214/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002215static void
paul718e3742002-12-13 20:15:29 +00002216route_set_originator_id_free (void *rule)
2217{
2218 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2219}
2220
Timo Teräs2aa640b2014-05-20 08:57:26 +03002221/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002222struct route_map_rule_cmd route_set_originator_id_cmd =
2223{
2224 "originator-id",
2225 route_set_originator_id,
2226 route_set_originator_id_compile,
2227 route_set_originator_id_free,
2228};
David Lamparter6b0655a2014-06-04 06:53:35 +02002229
paul718e3742002-12-13 20:15:29 +00002230/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002231static int
paul718e3742002-12-13 20:15:29 +00002232bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002233 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002234{
2235 int ret;
2236
2237 ret = route_map_add_match (index, command, arg);
2238 if (ret)
2239 {
2240 switch (ret)
2241 {
2242 case RMAP_RULE_MISSING:
2243 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2244 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002245 case RMAP_COMPILE_ERROR:
2246 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2247 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002248 }
2249 }
2250 return CMD_SUCCESS;
2251}
2252
2253/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002254static int
paul718e3742002-12-13 20:15:29 +00002255bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002256 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002257{
2258 int ret;
2259
2260 ret = route_map_delete_match (index, command, arg);
2261 if (ret)
2262 {
2263 switch (ret)
2264 {
2265 case RMAP_RULE_MISSING:
2266 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2267 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002268 case RMAP_COMPILE_ERROR:
2269 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2270 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002271 }
2272 }
2273 return CMD_SUCCESS;
2274}
2275
2276/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002277static int
paul718e3742002-12-13 20:15:29 +00002278bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002279 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002280{
2281 int ret;
2282
2283 ret = route_map_add_set (index, command, arg);
2284 if (ret)
2285 {
2286 switch (ret)
2287 {
2288 case RMAP_RULE_MISSING:
2289 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2290 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002291 case RMAP_COMPILE_ERROR:
2292 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2293 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002294 }
2295 }
2296 return CMD_SUCCESS;
2297}
2298
2299/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002300static int
paul718e3742002-12-13 20:15:29 +00002301bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002302 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002303{
2304 int ret;
2305
2306 ret = route_map_delete_set (index, command, arg);
2307 if (ret)
2308 {
2309 switch (ret)
2310 {
2311 case RMAP_RULE_MISSING:
2312 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2313 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002314 case RMAP_COMPILE_ERROR:
2315 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2316 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002317 }
2318 }
2319 return CMD_SUCCESS;
2320}
2321
2322/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002323static void
paulfd79ac92004-10-13 05:06:08 +00002324bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002325{
2326 int i;
2327 afi_t afi;
2328 safi_t safi;
2329 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002330 struct listnode *node, *nnode;
2331 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002332 struct bgp *bgp;
2333 struct peer *peer;
2334 struct peer_group *group;
2335 struct bgp_filter *filter;
2336 struct bgp_node *bn;
2337 struct bgp_static *bgp_static;
2338
2339 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002340 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002341 {
paul1eb8ef22005-04-07 07:30:20 +00002342 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002343 {
2344 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2345 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2346 {
2347 filter = &peer->filter[afi][safi];
2348
paulfee0f4c2004-09-13 05:12:46 +00002349 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002350 {
2351 if (filter->map[direct].name)
2352 filter->map[direct].map =
2353 route_map_lookup_by_name (filter->map[direct].name);
2354 else
2355 filter->map[direct].map = NULL;
2356 }
2357
2358 if (filter->usmap.name)
2359 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2360 else
2361 filter->usmap.map = NULL;
2362 }
2363 }
paul1eb8ef22005-04-07 07:30:20 +00002364 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002365 {
2366 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2367 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2368 {
2369 filter = &group->conf->filter[afi][safi];
2370
paulfee0f4c2004-09-13 05:12:46 +00002371 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002372 {
2373 if (filter->map[direct].name)
2374 filter->map[direct].map =
2375 route_map_lookup_by_name (filter->map[direct].name);
2376 else
2377 filter->map[direct].map = NULL;
2378 }
2379
2380 if (filter->usmap.name)
2381 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2382 else
2383 filter->usmap.map = NULL;
2384 }
2385 }
2386 }
2387
2388 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002389 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002390 {
paul1eb8ef22005-04-07 07:30:20 +00002391 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002392 {
2393 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2394 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2395 {
2396 if (peer->default_rmap[afi][safi].name)
2397 peer->default_rmap[afi][safi].map =
2398 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2399 else
2400 peer->default_rmap[afi][safi].map = NULL;
2401 }
2402 }
2403 }
2404
2405 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002406 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002407 {
2408 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2409 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2410 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2411 bn = bgp_route_next (bn))
2412 if ((bgp_static = bn->info) != NULL)
2413 {
2414 if (bgp_static->rmap.name)
2415 bgp_static->rmap.map =
2416 route_map_lookup_by_name (bgp_static->rmap.name);
2417 else
2418 bgp_static->rmap.map = NULL;
2419 }
2420 }
2421
2422 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002423 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002424 {
2425 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2426 {
2427 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2428 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2429 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2430#ifdef HAVE_IPV6
2431 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2432 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2433 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2434#endif /* HAVE_IPV6 */
2435 }
2436 }
2437}
David Lamparter6b0655a2014-06-04 06:53:35 +02002438
paulfee0f4c2004-09-13 05:12:46 +00002439DEFUN (match_peer,
2440 match_peer_cmd,
2441 "match peer (A.B.C.D|X:X::X:X)",
2442 MATCH_STR
2443 "Match peer address\n"
2444 "IPv6 address of peer\n"
2445 "IP address of peer\n")
2446{
2447 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2448}
2449
2450DEFUN (match_peer_local,
2451 match_peer_local_cmd,
2452 "match peer local",
2453 MATCH_STR
2454 "Match peer address\n"
2455 "Static or Redistributed routes\n")
2456{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002457 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002458}
2459
2460DEFUN (no_match_peer,
2461 no_match_peer_cmd,
2462 "no match peer",
2463 NO_STR
2464 MATCH_STR
2465 "Match peer address\n")
2466{
2467 if (argc == 0)
2468 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2469
2470 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2471}
2472
2473ALIAS (no_match_peer,
2474 no_match_peer_val_cmd,
2475 "no match peer (A.B.C.D|X:X::X:X)",
2476 NO_STR
2477 MATCH_STR
2478 "Match peer address\n"
2479 "IPv6 address of peer\n"
2480 "IP address of peer\n")
2481
2482ALIAS (no_match_peer,
2483 no_match_peer_local_cmd,
2484 "no match peer local",
2485 NO_STR
2486 MATCH_STR
2487 "Match peer address\n"
2488 "Static or Redistributed routes\n")
2489
paul718e3742002-12-13 20:15:29 +00002490DEFUN (match_ip_address,
2491 match_ip_address_cmd,
2492 "match ip address (<1-199>|<1300-2699>|WORD)",
2493 MATCH_STR
2494 IP_STR
2495 "Match address of route\n"
2496 "IP access-list number\n"
2497 "IP access-list number (expanded range)\n"
2498 "IP Access-list name\n")
2499{
2500 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2501}
2502
2503DEFUN (no_match_ip_address,
2504 no_match_ip_address_cmd,
2505 "no match ip address",
2506 NO_STR
2507 MATCH_STR
2508 IP_STR
2509 "Match address of route\n")
2510{
2511 if (argc == 0)
2512 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2513
2514 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2515}
2516
2517ALIAS (no_match_ip_address,
2518 no_match_ip_address_val_cmd,
2519 "no match ip address (<1-199>|<1300-2699>|WORD)",
2520 NO_STR
2521 MATCH_STR
2522 IP_STR
2523 "Match address of route\n"
2524 "IP access-list number\n"
2525 "IP access-list number (expanded range)\n"
2526 "IP Access-list name\n")
2527
2528DEFUN (match_ip_next_hop,
2529 match_ip_next_hop_cmd,
2530 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2531 MATCH_STR
2532 IP_STR
2533 "Match next-hop address of route\n"
2534 "IP access-list number\n"
2535 "IP access-list number (expanded range)\n"
2536 "IP Access-list name\n")
2537{
2538 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2539}
2540
2541DEFUN (no_match_ip_next_hop,
2542 no_match_ip_next_hop_cmd,
2543 "no match ip next-hop",
2544 NO_STR
2545 MATCH_STR
2546 IP_STR
2547 "Match next-hop address of route\n")
2548{
2549 if (argc == 0)
2550 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2551
2552 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2553}
2554
2555ALIAS (no_match_ip_next_hop,
2556 no_match_ip_next_hop_val_cmd,
2557 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2558 NO_STR
2559 MATCH_STR
2560 IP_STR
2561 "Match next-hop address of route\n"
2562 "IP access-list number\n"
2563 "IP access-list number (expanded range)\n"
2564 "IP Access-list name\n")
2565
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002566/* match probability { */
2567
2568DEFUN (match_probability,
2569 match_probability_cmd,
2570 "match probability <0-100>",
2571 MATCH_STR
2572 "Match portion of routes defined by percentage value\n"
2573 "Percentage of routes\n")
2574{
2575 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2576}
2577
2578DEFUN (no_match_probability,
2579 no_match_probability_cmd,
2580 "no match probability",
2581 NO_STR
2582 MATCH_STR
2583 "Match portion of routes defined by percentage value\n")
2584{
2585 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2586}
2587
2588ALIAS (no_match_probability,
2589 no_match_probability_val_cmd,
2590 "no match probability <1-99>",
2591 NO_STR
2592 MATCH_STR
2593 "Match portion of routes defined by percentage value\n"
2594 "Percentage of routes\n")
2595
2596/* } */
2597
hassoc1643bb2005-02-02 16:43:17 +00002598DEFUN (match_ip_route_source,
2599 match_ip_route_source_cmd,
2600 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2601 MATCH_STR
2602 IP_STR
2603 "Match advertising source address of route\n"
2604 "IP access-list number\n"
2605 "IP access-list number (expanded range)\n"
2606 "IP standard access-list name\n")
2607{
2608 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2609}
2610
2611DEFUN (no_match_ip_route_source,
2612 no_match_ip_route_source_cmd,
2613 "no match ip route-source",
2614 NO_STR
2615 MATCH_STR
2616 IP_STR
2617 "Match advertising source address of route\n")
2618{
2619 if (argc == 0)
2620 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2621
2622 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2623}
2624
2625ALIAS (no_match_ip_route_source,
2626 no_match_ip_route_source_val_cmd,
2627 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2628 NO_STR
2629 MATCH_STR
2630 IP_STR
2631 "Match advertising source address of route\n"
2632 "IP access-list number\n"
2633 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002634 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002635
paul718e3742002-12-13 20:15:29 +00002636DEFUN (match_ip_address_prefix_list,
2637 match_ip_address_prefix_list_cmd,
2638 "match ip address prefix-list WORD",
2639 MATCH_STR
2640 IP_STR
2641 "Match address of route\n"
2642 "Match entries of prefix-lists\n"
2643 "IP prefix-list name\n")
2644{
2645 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2646}
2647
2648DEFUN (no_match_ip_address_prefix_list,
2649 no_match_ip_address_prefix_list_cmd,
2650 "no match ip address prefix-list",
2651 NO_STR
2652 MATCH_STR
2653 IP_STR
2654 "Match address of route\n"
2655 "Match entries of prefix-lists\n")
2656{
2657 if (argc == 0)
2658 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2659
2660 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2661}
2662
2663ALIAS (no_match_ip_address_prefix_list,
2664 no_match_ip_address_prefix_list_val_cmd,
2665 "no match ip address prefix-list WORD",
2666 NO_STR
2667 MATCH_STR
2668 IP_STR
2669 "Match address of route\n"
2670 "Match entries of prefix-lists\n"
2671 "IP prefix-list name\n")
2672
2673DEFUN (match_ip_next_hop_prefix_list,
2674 match_ip_next_hop_prefix_list_cmd,
2675 "match ip next-hop prefix-list WORD",
2676 MATCH_STR
2677 IP_STR
2678 "Match next-hop address of route\n"
2679 "Match entries of prefix-lists\n"
2680 "IP prefix-list name\n")
2681{
2682 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2683}
2684
2685DEFUN (no_match_ip_next_hop_prefix_list,
2686 no_match_ip_next_hop_prefix_list_cmd,
2687 "no match ip next-hop prefix-list",
2688 NO_STR
2689 MATCH_STR
2690 IP_STR
2691 "Match next-hop address of route\n"
2692 "Match entries of prefix-lists\n")
2693{
2694 if (argc == 0)
2695 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2696
2697 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2698}
2699
2700ALIAS (no_match_ip_next_hop_prefix_list,
2701 no_match_ip_next_hop_prefix_list_val_cmd,
2702 "no match ip next-hop prefix-list WORD",
2703 NO_STR
2704 MATCH_STR
2705 IP_STR
2706 "Match next-hop address of route\n"
2707 "Match entries of prefix-lists\n"
2708 "IP prefix-list name\n")
2709
hassoc1643bb2005-02-02 16:43:17 +00002710DEFUN (match_ip_route_source_prefix_list,
2711 match_ip_route_source_prefix_list_cmd,
2712 "match ip route-source prefix-list WORD",
2713 MATCH_STR
2714 IP_STR
2715 "Match advertising source address of route\n"
2716 "Match entries of prefix-lists\n"
2717 "IP prefix-list name\n")
2718{
2719 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2720}
2721
2722DEFUN (no_match_ip_route_source_prefix_list,
2723 no_match_ip_route_source_prefix_list_cmd,
2724 "no match ip route-source prefix-list",
2725 NO_STR
2726 MATCH_STR
2727 IP_STR
2728 "Match advertising source address of route\n"
2729 "Match entries of prefix-lists\n")
2730{
2731 if (argc == 0)
2732 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2733
2734 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2735}
2736
2737ALIAS (no_match_ip_route_source_prefix_list,
2738 no_match_ip_route_source_prefix_list_val_cmd,
2739 "no match ip route-source prefix-list WORD",
2740 NO_STR
2741 MATCH_STR
2742 IP_STR
2743 "Match advertising source address of route\n"
2744 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002745 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002746
paul718e3742002-12-13 20:15:29 +00002747DEFUN (match_metric,
2748 match_metric_cmd,
2749 "match metric <0-4294967295>",
2750 MATCH_STR
2751 "Match metric of route\n"
2752 "Metric value\n")
2753{
2754 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2755}
2756
2757DEFUN (no_match_metric,
2758 no_match_metric_cmd,
2759 "no match metric",
2760 NO_STR
2761 MATCH_STR
2762 "Match metric of route\n")
2763{
2764 if (argc == 0)
2765 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2766
2767 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2768}
2769
2770ALIAS (no_match_metric,
2771 no_match_metric_val_cmd,
2772 "no match metric <0-4294967295>",
2773 NO_STR
2774 MATCH_STR
2775 "Match metric of route\n"
2776 "Metric value\n")
2777
2778DEFUN (match_community,
2779 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002780 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002781 MATCH_STR
2782 "Match BGP community list\n"
2783 "Community-list number (standard)\n"
2784 "Community-list number (expanded)\n"
2785 "Community-list name\n")
2786{
2787 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2788}
2789
2790DEFUN (match_community_exact,
2791 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002792 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002793 MATCH_STR
2794 "Match BGP community list\n"
2795 "Community-list number (standard)\n"
2796 "Community-list number (expanded)\n"
2797 "Community-list name\n"
2798 "Do exact matching of communities\n")
2799{
2800 int ret;
2801 char *argstr;
2802
2803 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2804 strlen (argv[0]) + strlen ("exact-match") + 2);
2805
2806 sprintf (argstr, "%s exact-match", argv[0]);
2807
2808 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2809
2810 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2811
2812 return ret;
2813}
2814
2815DEFUN (no_match_community,
2816 no_match_community_cmd,
2817 "no match community",
2818 NO_STR
2819 MATCH_STR
2820 "Match BGP community list\n")
2821{
2822 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2823}
2824
2825ALIAS (no_match_community,
2826 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002827 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002828 NO_STR
2829 MATCH_STR
2830 "Match BGP community list\n"
2831 "Community-list number (standard)\n"
2832 "Community-list number (expanded)\n"
2833 "Community-list name\n")
2834
2835ALIAS (no_match_community,
2836 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002837 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002838 NO_STR
2839 MATCH_STR
2840 "Match BGP community list\n"
2841 "Community-list number (standard)\n"
2842 "Community-list number (expanded)\n"
2843 "Community-list name\n"
2844 "Do exact matching of communities\n")
2845
paul73ffb252003-04-19 15:49:49 +00002846DEFUN (match_ecommunity,
2847 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002848 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002849 MATCH_STR
2850 "Match BGP/VPN extended community list\n"
2851 "Extended community-list number (standard)\n"
2852 "Extended community-list number (expanded)\n"
2853 "Extended community-list name\n")
2854{
2855 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2856}
2857
2858DEFUN (no_match_ecommunity,
2859 no_match_ecommunity_cmd,
2860 "no match extcommunity",
2861 NO_STR
2862 MATCH_STR
2863 "Match BGP/VPN extended community list\n")
2864{
2865 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2866}
2867
2868ALIAS (no_match_ecommunity,
2869 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002870 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002871 NO_STR
2872 MATCH_STR
2873 "Match BGP/VPN extended community list\n"
2874 "Extended community-list number (standard)\n"
2875 "Extended community-list number (expanded)\n"
2876 "Extended community-list name\n")
2877
paul718e3742002-12-13 20:15:29 +00002878DEFUN (match_aspath,
2879 match_aspath_cmd,
2880 "match as-path WORD",
2881 MATCH_STR
2882 "Match BGP AS path list\n"
2883 "AS path access-list name\n")
2884{
2885 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2886}
2887
2888DEFUN (no_match_aspath,
2889 no_match_aspath_cmd,
2890 "no match as-path",
2891 NO_STR
2892 MATCH_STR
2893 "Match BGP AS path list\n")
2894{
2895 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2896}
2897
2898ALIAS (no_match_aspath,
2899 no_match_aspath_val_cmd,
2900 "no match as-path WORD",
2901 NO_STR
2902 MATCH_STR
2903 "Match BGP AS path list\n"
2904 "AS path access-list name\n")
2905
2906DEFUN (match_origin,
2907 match_origin_cmd,
2908 "match origin (egp|igp|incomplete)",
2909 MATCH_STR
2910 "BGP origin code\n"
2911 "remote EGP\n"
2912 "local IGP\n"
2913 "unknown heritage\n")
2914{
2915 if (strncmp (argv[0], "igp", 2) == 0)
2916 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2917 if (strncmp (argv[0], "egp", 1) == 0)
2918 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2919 if (strncmp (argv[0], "incomplete", 2) == 0)
2920 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2921
2922 return CMD_WARNING;
2923}
2924
2925DEFUN (no_match_origin,
2926 no_match_origin_cmd,
2927 "no match origin",
2928 NO_STR
2929 MATCH_STR
2930 "BGP origin code\n")
2931{
2932 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2933}
2934
2935ALIAS (no_match_origin,
2936 no_match_origin_val_cmd,
2937 "no match origin (egp|igp|incomplete)",
2938 NO_STR
2939 MATCH_STR
2940 "BGP origin code\n"
2941 "remote EGP\n"
2942 "local IGP\n"
2943 "unknown heritage\n")
2944
2945DEFUN (set_ip_nexthop,
2946 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002947 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002948 SET_STR
2949 IP_STR
2950 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002951 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002952{
2953 union sockunion su;
2954 int ret;
2955
2956 ret = str2sockunion (argv[0], &su);
2957 if (ret < 0)
2958 {
2959 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2960 return CMD_WARNING;
2961 }
2962
2963 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2964}
2965
paulaf5cd0a2003-11-02 07:24:40 +00002966DEFUN (set_ip_nexthop_peer,
2967 set_ip_nexthop_peer_cmd,
2968 "set ip next-hop peer-address",
2969 SET_STR
2970 IP_STR
2971 "Next hop address\n"
2972 "Use peer address (for BGP only)\n")
2973{
2974 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2975}
2976
paul94f2b392005-06-28 12:44:16 +00002977DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002978 no_set_ip_nexthop_peer_cmd,
2979 "no set ip next-hop peer-address",
2980 NO_STR
2981 SET_STR
2982 IP_STR
2983 "Next hop address\n"
2984 "Use peer address (for BGP only)\n")
2985{
2986 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2987}
2988
2989
paul718e3742002-12-13 20:15:29 +00002990DEFUN (no_set_ip_nexthop,
2991 no_set_ip_nexthop_cmd,
2992 "no set ip next-hop",
2993 NO_STR
2994 SET_STR
paul718e3742002-12-13 20:15:29 +00002995 "Next hop address\n")
2996{
paulaf5cd0a2003-11-02 07:24:40 +00002997 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002998 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2999
3000 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3001}
3002
3003ALIAS (no_set_ip_nexthop,
3004 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003005 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003006 NO_STR
3007 SET_STR
3008 IP_STR
3009 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003010 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003011
3012DEFUN (set_metric,
3013 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00003014 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00003015 SET_STR
3016 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00003017 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00003018{
3019 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3020}
3021
paul73ffb252003-04-19 15:49:49 +00003022ALIAS (set_metric,
3023 set_metric_addsub_cmd,
3024 "set metric <+/-metric>",
3025 SET_STR
3026 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003027 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003028
paul718e3742002-12-13 20:15:29 +00003029DEFUN (no_set_metric,
3030 no_set_metric_cmd,
3031 "no set metric",
3032 NO_STR
3033 SET_STR
3034 "Metric value for destination routing protocol\n")
3035{
3036 if (argc == 0)
3037 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3038
3039 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3040}
3041
3042ALIAS (no_set_metric,
3043 no_set_metric_val_cmd,
3044 "no set metric <0-4294967295>",
3045 NO_STR
3046 SET_STR
3047 "Metric value for destination routing protocol\n"
3048 "Metric value\n")
3049
3050DEFUN (set_local_pref,
3051 set_local_pref_cmd,
3052 "set local-preference <0-4294967295>",
3053 SET_STR
3054 "BGP local preference path attribute\n"
3055 "Preference value\n")
3056{
3057 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3058}
3059
3060DEFUN (no_set_local_pref,
3061 no_set_local_pref_cmd,
3062 "no set local-preference",
3063 NO_STR
3064 SET_STR
3065 "BGP local preference path attribute\n")
3066{
3067 if (argc == 0)
3068 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3069
3070 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3071}
3072
3073ALIAS (no_set_local_pref,
3074 no_set_local_pref_val_cmd,
3075 "no set local-preference <0-4294967295>",
3076 NO_STR
3077 SET_STR
3078 "BGP local preference path attribute\n"
3079 "Preference value\n")
3080
3081DEFUN (set_weight,
3082 set_weight_cmd,
3083 "set weight <0-4294967295>",
3084 SET_STR
3085 "BGP weight for routing table\n"
3086 "Weight value\n")
3087{
3088 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3089}
3090
3091DEFUN (no_set_weight,
3092 no_set_weight_cmd,
3093 "no set weight",
3094 NO_STR
3095 SET_STR
3096 "BGP weight for routing table\n")
3097{
3098 if (argc == 0)
3099 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3100
3101 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3102}
3103
3104ALIAS (no_set_weight,
3105 no_set_weight_val_cmd,
3106 "no set weight <0-4294967295>",
3107 NO_STR
3108 SET_STR
3109 "BGP weight for routing table\n"
3110 "Weight value\n")
3111
3112DEFUN (set_aspath_prepend,
3113 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003114 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003115 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003116 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003117 "Prepend to the as-path\n"
3118 "AS number\n")
3119{
3120 int ret;
3121 char *str;
3122
3123 str = argv_concat (argv, argc, 0);
3124 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3125 XFREE (MTYPE_TMP, str);
3126
3127 return ret;
3128}
3129
3130DEFUN (no_set_aspath_prepend,
3131 no_set_aspath_prepend_cmd,
3132 "no set as-path prepend",
3133 NO_STR
3134 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003135 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003136 "Prepend to the as-path\n")
3137{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003138 int ret;
3139 char *str;
3140
3141 if (argc == 0)
3142 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3143
3144 str = argv_concat (argv, argc, 0);
3145 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3146 XFREE (MTYPE_TMP, str);
3147 return ret;
paul718e3742002-12-13 20:15:29 +00003148}
3149
3150ALIAS (no_set_aspath_prepend,
3151 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003152 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003153 NO_STR
3154 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003155 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003156 "Prepend to the as-path\n"
3157 "AS number\n")
3158
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003159DEFUN (set_aspath_exclude,
3160 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003161 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003162 SET_STR
3163 "Transform BGP AS-path attribute\n"
3164 "Exclude from the as-path\n"
3165 "AS number\n")
3166{
3167 int ret;
3168 char *str;
3169
3170 str = argv_concat (argv, argc, 0);
3171 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3172 XFREE (MTYPE_TMP, str);
3173 return ret;
3174}
3175
3176DEFUN (no_set_aspath_exclude,
3177 no_set_aspath_exclude_cmd,
3178 "no set as-path exclude",
3179 NO_STR
3180 SET_STR
3181 "Transform BGP AS_PATH attribute\n"
3182 "Exclude from the as-path\n")
3183{
3184 int ret;
3185 char *str;
3186
3187 if (argc == 0)
3188 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3189
3190 str = argv_concat (argv, argc, 0);
3191 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3192 XFREE (MTYPE_TMP, str);
3193 return ret;
3194}
3195
3196ALIAS (no_set_aspath_exclude,
3197 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003198 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003199 NO_STR
3200 SET_STR
3201 "Transform BGP AS_PATH attribute\n"
3202 "Exclude from the as-path\n"
3203 "AS number\n")
3204
paul718e3742002-12-13 20:15:29 +00003205DEFUN (set_community,
3206 set_community_cmd,
3207 "set community .AA:NN",
3208 SET_STR
3209 "BGP community attribute\n"
3210 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3211{
3212 int i;
3213 int first = 0;
3214 int additive = 0;
3215 struct buffer *b;
3216 struct community *com = NULL;
3217 char *str;
3218 char *argstr;
3219 int ret;
3220
3221 b = buffer_new (1024);
3222
3223 for (i = 0; i < argc; i++)
3224 {
3225 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3226 {
3227 additive = 1;
3228 continue;
3229 }
3230
3231 if (first)
3232 buffer_putc (b, ' ');
3233 else
3234 first = 1;
3235
3236 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3237 {
3238 buffer_putstr (b, "internet");
3239 continue;
3240 }
3241 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3242 {
3243 buffer_putstr (b, "local-AS");
3244 continue;
3245 }
3246 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3247 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3248 {
3249 buffer_putstr (b, "no-advertise");
3250 continue;
3251 }
3252 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3253 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3254 {
3255 buffer_putstr (b, "no-export");
3256 continue;
3257 }
3258 buffer_putstr (b, argv[i]);
3259 }
3260 buffer_putc (b, '\0');
3261
3262 /* Fetch result string then compile it to communities attribute. */
3263 str = buffer_getstr (b);
3264 buffer_free (b);
3265
3266 if (str)
3267 {
3268 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003269 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003270 }
3271
3272 /* Can't compile user input into communities attribute. */
3273 if (! com)
3274 {
3275 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3276 return CMD_WARNING;
3277 }
3278
3279 /* Set communites attribute string. */
3280 str = community_str (com);
3281
3282 if (additive)
3283 {
3284 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3285 strcpy (argstr, str);
3286 strcpy (argstr + strlen (str), " additive");
3287 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3288 XFREE (MTYPE_TMP, argstr);
3289 }
3290 else
3291 ret = bgp_route_set_add (vty, vty->index, "community", str);
3292
3293 community_free (com);
3294
3295 return ret;
3296}
3297
3298DEFUN (set_community_none,
3299 set_community_none_cmd,
3300 "set community none",
3301 SET_STR
3302 "BGP community attribute\n"
3303 "No community attribute\n")
3304{
3305 return bgp_route_set_add (vty, vty->index, "community", "none");
3306}
3307
3308DEFUN (no_set_community,
3309 no_set_community_cmd,
3310 "no set community",
3311 NO_STR
3312 SET_STR
3313 "BGP community attribute\n")
3314{
3315 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3316}
3317
3318ALIAS (no_set_community,
3319 no_set_community_val_cmd,
3320 "no set community .AA:NN",
3321 NO_STR
3322 SET_STR
3323 "BGP community attribute\n"
3324 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3325
3326ALIAS (no_set_community,
3327 no_set_community_none_cmd,
3328 "no set community none",
3329 NO_STR
3330 SET_STR
3331 "BGP community attribute\n"
3332 "No community attribute\n")
3333
3334DEFUN (set_community_delete,
3335 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003336 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003337 SET_STR
3338 "set BGP community list (for deletion)\n"
3339 "Community-list number (standard)\n"
3340 "Communitly-list number (expanded)\n"
3341 "Community-list name\n"
3342 "Delete matching communities\n")
3343{
3344 char *str;
3345
3346 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3347 strcpy (str, argv[0]);
3348 strcpy (str + strlen (argv[0]), " delete");
3349
3350 bgp_route_set_add (vty, vty->index, "comm-list", str);
3351
3352 XFREE (MTYPE_TMP, str);
3353 return CMD_SUCCESS;
3354}
3355
3356DEFUN (no_set_community_delete,
3357 no_set_community_delete_cmd,
3358 "no set comm-list",
3359 NO_STR
3360 SET_STR
3361 "set BGP community list (for deletion)\n")
3362{
3363 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3364}
3365
3366ALIAS (no_set_community_delete,
3367 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003368 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003369 NO_STR
3370 SET_STR
3371 "set BGP community list (for deletion)\n"
3372 "Community-list number (standard)\n"
3373 "Communitly-list number (expanded)\n"
3374 "Community-list name\n"
3375 "Delete matching communities\n")
3376
3377DEFUN (set_ecommunity_rt,
3378 set_ecommunity_rt_cmd,
3379 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3380 SET_STR
3381 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003382 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003383 "VPN extended community\n")
3384{
3385 int ret;
3386 char *str;
3387
3388 str = argv_concat (argv, argc, 0);
3389 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3390 XFREE (MTYPE_TMP, str);
3391
3392 return ret;
3393}
3394
3395DEFUN (no_set_ecommunity_rt,
3396 no_set_ecommunity_rt_cmd,
3397 "no set extcommunity rt",
3398 NO_STR
3399 SET_STR
3400 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003401 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003402{
3403 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3404}
3405
3406ALIAS (no_set_ecommunity_rt,
3407 no_set_ecommunity_rt_val_cmd,
3408 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3409 NO_STR
3410 SET_STR
3411 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003412 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003413 "VPN extended community\n")
3414
3415DEFUN (set_ecommunity_soo,
3416 set_ecommunity_soo_cmd,
3417 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3418 SET_STR
3419 "BGP extended community attribute\n"
3420 "Site-of-Origin extended community\n"
3421 "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 soo", str);
3428 XFREE (MTYPE_TMP, str);
3429 return ret;
3430}
3431
3432DEFUN (no_set_ecommunity_soo,
3433 no_set_ecommunity_soo_cmd,
3434 "no set extcommunity soo",
3435 NO_STR
3436 SET_STR
3437 "BGP extended community attribute\n"
3438 "Site-of-Origin extended community\n")
3439{
3440 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3441}
3442
3443ALIAS (no_set_ecommunity_soo,
3444 no_set_ecommunity_soo_val_cmd,
3445 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3446 NO_STR
3447 SET_STR
3448 "BGP extended community attribute\n"
3449 "Site-of-Origin extended community\n"
3450 "VPN extended community\n")
3451
3452DEFUN (set_origin,
3453 set_origin_cmd,
3454 "set origin (egp|igp|incomplete)",
3455 SET_STR
3456 "BGP origin code\n"
3457 "remote EGP\n"
3458 "local IGP\n"
3459 "unknown heritage\n")
3460{
3461 if (strncmp (argv[0], "igp", 2) == 0)
3462 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3463 if (strncmp (argv[0], "egp", 1) == 0)
3464 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3465 if (strncmp (argv[0], "incomplete", 2) == 0)
3466 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3467
3468 return CMD_WARNING;
3469}
3470
3471DEFUN (no_set_origin,
3472 no_set_origin_cmd,
3473 "no set origin",
3474 NO_STR
3475 SET_STR
3476 "BGP origin code\n")
3477{
3478 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3479}
3480
3481ALIAS (no_set_origin,
3482 no_set_origin_val_cmd,
3483 "no set origin (egp|igp|incomplete)",
3484 NO_STR
3485 SET_STR
3486 "BGP origin code\n"
3487 "remote EGP\n"
3488 "local IGP\n"
3489 "unknown heritage\n")
3490
3491DEFUN (set_atomic_aggregate,
3492 set_atomic_aggregate_cmd,
3493 "set atomic-aggregate",
3494 SET_STR
3495 "BGP atomic aggregate attribute\n" )
3496{
3497 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3498}
3499
3500DEFUN (no_set_atomic_aggregate,
3501 no_set_atomic_aggregate_cmd,
3502 "no set atomic-aggregate",
3503 NO_STR
3504 SET_STR
3505 "BGP atomic aggregate attribute\n" )
3506{
3507 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3508}
3509
3510DEFUN (set_aggregator_as,
3511 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003512 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003513 SET_STR
3514 "BGP aggregator attribute\n"
3515 "AS number of aggregator\n"
3516 "AS number\n"
3517 "IP address of aggregator\n")
3518{
3519 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003520 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003521 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003522 char *argstr;
3523
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003524 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003525
paul718e3742002-12-13 20:15:29 +00003526 ret = inet_aton (argv[1], &address);
3527 if (ret == 0)
3528 {
3529 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3530 return CMD_WARNING;
3531 }
3532
3533 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3534 strlen (argv[0]) + strlen (argv[1]) + 2);
3535
3536 sprintf (argstr, "%s %s", argv[0], argv[1]);
3537
3538 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3539
3540 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3541
3542 return ret;
3543}
3544
3545DEFUN (no_set_aggregator_as,
3546 no_set_aggregator_as_cmd,
3547 "no set aggregator as",
3548 NO_STR
3549 SET_STR
3550 "BGP aggregator attribute\n"
3551 "AS number of aggregator\n")
3552{
3553 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003554 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003555 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003556 char *argstr;
3557
3558 if (argv == 0)
3559 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3560
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003561 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003562
3563 ret = inet_aton (argv[1], &address);
3564 if (ret == 0)
3565 {
3566 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3567 return CMD_WARNING;
3568 }
3569
3570 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3571 strlen (argv[0]) + strlen (argv[1]) + 2);
3572
3573 sprintf (argstr, "%s %s", argv[0], argv[1]);
3574
3575 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3576
3577 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3578
3579 return ret;
3580}
3581
3582ALIAS (no_set_aggregator_as,
3583 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003584 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003585 NO_STR
3586 SET_STR
3587 "BGP aggregator attribute\n"
3588 "AS number of aggregator\n"
3589 "AS number\n"
3590 "IP address of aggregator\n")
3591
David Lamparter6b0655a2014-06-04 06:53:35 +02003592
paul718e3742002-12-13 20:15:29 +00003593#ifdef HAVE_IPV6
3594DEFUN (match_ipv6_address,
3595 match_ipv6_address_cmd,
3596 "match ipv6 address WORD",
3597 MATCH_STR
3598 IPV6_STR
3599 "Match IPv6 address of route\n"
3600 "IPv6 access-list name\n")
3601{
3602 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3603}
3604
3605DEFUN (no_match_ipv6_address,
3606 no_match_ipv6_address_cmd,
3607 "no match ipv6 address WORD",
3608 NO_STR
3609 MATCH_STR
3610 IPV6_STR
3611 "Match IPv6 address of route\n"
3612 "IPv6 access-list name\n")
3613{
3614 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3615}
3616
3617DEFUN (match_ipv6_next_hop,
3618 match_ipv6_next_hop_cmd,
3619 "match ipv6 next-hop X:X::X:X",
3620 MATCH_STR
3621 IPV6_STR
3622 "Match IPv6 next-hop address of route\n"
3623 "IPv6 address of next hop\n")
3624{
3625 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3626}
3627
3628DEFUN (no_match_ipv6_next_hop,
3629 no_match_ipv6_next_hop_cmd,
3630 "no match ipv6 next-hop X:X::X:X",
3631 NO_STR
3632 MATCH_STR
3633 IPV6_STR
3634 "Match IPv6 next-hop address of route\n"
3635 "IPv6 address of next hop\n")
3636{
3637 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3638}
3639
3640DEFUN (match_ipv6_address_prefix_list,
3641 match_ipv6_address_prefix_list_cmd,
3642 "match ipv6 address prefix-list WORD",
3643 MATCH_STR
3644 IPV6_STR
3645 "Match address of route\n"
3646 "Match entries of prefix-lists\n"
3647 "IP prefix-list name\n")
3648{
3649 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3650}
3651
3652DEFUN (no_match_ipv6_address_prefix_list,
3653 no_match_ipv6_address_prefix_list_cmd,
3654 "no match ipv6 address prefix-list WORD",
3655 NO_STR
3656 MATCH_STR
3657 IPV6_STR
3658 "Match address of route\n"
3659 "Match entries of prefix-lists\n"
3660 "IP prefix-list name\n")
3661{
3662 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3663}
3664
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003665DEFUN (set_ipv6_nexthop_peer,
3666 set_ipv6_nexthop_peer_cmd,
3667 "set ipv6 next-hop peer-address",
3668 SET_STR
3669 IPV6_STR
3670 "Next hop address\n"
3671 "Use peer address (for BGP only)\n")
3672{
3673 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3674}
3675
3676DEFUN (no_set_ipv6_nexthop_peer,
3677 no_set_ipv6_nexthop_peer_cmd,
3678 "no set ipv6 next-hop peer-address",
3679 NO_STR
3680 SET_STR
3681 IPV6_STR
3682 "IPv6 next-hop address\n"
3683 )
3684{
3685 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3686}
3687
paul718e3742002-12-13 20:15:29 +00003688DEFUN (set_ipv6_nexthop_global,
3689 set_ipv6_nexthop_global_cmd,
3690 "set ipv6 next-hop global X:X::X:X",
3691 SET_STR
3692 IPV6_STR
3693 "IPv6 next-hop address\n"
3694 "IPv6 global address\n"
3695 "IPv6 address of next hop\n")
3696{
3697 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3698}
3699
3700DEFUN (no_set_ipv6_nexthop_global,
3701 no_set_ipv6_nexthop_global_cmd,
3702 "no set ipv6 next-hop global",
3703 NO_STR
3704 SET_STR
3705 IPV6_STR
3706 "IPv6 next-hop address\n"
3707 "IPv6 global address\n")
3708{
3709 if (argc == 0)
3710 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3711
3712 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3713}
3714
3715ALIAS (no_set_ipv6_nexthop_global,
3716 no_set_ipv6_nexthop_global_val_cmd,
3717 "no set ipv6 next-hop global X:X::X:X",
3718 NO_STR
3719 SET_STR
3720 IPV6_STR
3721 "IPv6 next-hop address\n"
3722 "IPv6 global address\n"
3723 "IPv6 address of next hop\n")
3724
3725DEFUN (set_ipv6_nexthop_local,
3726 set_ipv6_nexthop_local_cmd,
3727 "set ipv6 next-hop local X:X::X:X",
3728 SET_STR
3729 IPV6_STR
3730 "IPv6 next-hop address\n"
3731 "IPv6 local address\n"
3732 "IPv6 address of next hop\n")
3733{
3734 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3735}
3736
3737DEFUN (no_set_ipv6_nexthop_local,
3738 no_set_ipv6_nexthop_local_cmd,
3739 "no set ipv6 next-hop local",
3740 NO_STR
3741 SET_STR
3742 IPV6_STR
3743 "IPv6 next-hop address\n"
3744 "IPv6 local address\n")
3745{
3746 if (argc == 0)
3747 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3748
3749 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3750}
3751
3752ALIAS (no_set_ipv6_nexthop_local,
3753 no_set_ipv6_nexthop_local_val_cmd,
3754 "no set ipv6 next-hop local X:X::X:X",
3755 NO_STR
3756 SET_STR
3757 IPV6_STR
3758 "IPv6 next-hop address\n"
3759 "IPv6 local address\n"
3760 "IPv6 address of next hop\n")
3761#endif /* HAVE_IPV6 */
3762
3763DEFUN (set_vpnv4_nexthop,
3764 set_vpnv4_nexthop_cmd,
3765 "set vpnv4 next-hop A.B.C.D",
3766 SET_STR
3767 "VPNv4 information\n"
3768 "VPNv4 next-hop address\n"
3769 "IP address of next hop\n")
3770{
3771 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3772}
3773
3774DEFUN (no_set_vpnv4_nexthop,
3775 no_set_vpnv4_nexthop_cmd,
3776 "no set vpnv4 next-hop",
3777 NO_STR
3778 SET_STR
3779 "VPNv4 information\n"
3780 "VPNv4 next-hop address\n")
3781{
3782 if (argc == 0)
3783 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3784
3785 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3786}
3787
3788ALIAS (no_set_vpnv4_nexthop,
3789 no_set_vpnv4_nexthop_val_cmd,
3790 "no set vpnv4 next-hop A.B.C.D",
3791 NO_STR
3792 SET_STR
3793 "VPNv4 information\n"
3794 "VPNv4 next-hop address\n"
3795 "IP address of next hop\n")
3796
3797DEFUN (set_originator_id,
3798 set_originator_id_cmd,
3799 "set originator-id A.B.C.D",
3800 SET_STR
3801 "BGP originator ID attribute\n"
3802 "IP address of originator\n")
3803{
3804 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3805}
3806
3807DEFUN (no_set_originator_id,
3808 no_set_originator_id_cmd,
3809 "no set originator-id",
3810 NO_STR
3811 SET_STR
3812 "BGP originator ID attribute\n")
3813{
3814 if (argc == 0)
3815 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3816
3817 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3818}
3819
3820ALIAS (no_set_originator_id,
3821 no_set_originator_id_val_cmd,
3822 "no set originator-id A.B.C.D",
3823 NO_STR
3824 SET_STR
3825 "BGP originator ID attribute\n"
3826 "IP address of originator\n")
3827
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003828DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003829 set_pathlimit_ttl_cmd,
3830 "set pathlimit ttl <1-255>",
3831 SET_STR
3832 "BGP AS-Pathlimit attribute\n"
3833 "Set AS-Path Hop-count TTL\n")
3834{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003835 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003836}
3837
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003838DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003839 no_set_pathlimit_ttl_cmd,
3840 "no set pathlimit ttl",
3841 NO_STR
3842 SET_STR
3843 "BGP AS-Pathlimit attribute\n"
3844 "Set AS-Path Hop-count TTL\n")
3845{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003846 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003847}
3848
3849ALIAS (no_set_pathlimit_ttl,
3850 no_set_pathlimit_ttl_val_cmd,
3851 "no set pathlimit ttl <1-255>",
3852 NO_STR
3853 MATCH_STR
3854 "BGP AS-Pathlimit attribute\n"
3855 "Set AS-Path Hop-count TTL\n")
3856
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003857DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003858 match_pathlimit_as_cmd,
3859 "match pathlimit as <1-65535>",
3860 MATCH_STR
3861 "BGP AS-Pathlimit attribute\n"
3862 "Match Pathlimit AS number\n")
3863{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003864 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003865}
3866
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003867DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003868 no_match_pathlimit_as_cmd,
3869 "no match pathlimit as",
3870 NO_STR
3871 MATCH_STR
3872 "BGP AS-Pathlimit attribute\n"
3873 "Match Pathlimit AS number\n")
3874{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003875 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003876}
3877
3878ALIAS (no_match_pathlimit_as,
3879 no_match_pathlimit_as_val_cmd,
3880 "no match pathlimit as <1-65535>",
3881 NO_STR
3882 MATCH_STR
3883 "BGP AS-Pathlimit attribute\n"
3884 "Match Pathlimit ASN\n")
3885
David Lamparter6b0655a2014-06-04 06:53:35 +02003886
paul718e3742002-12-13 20:15:29 +00003887/* Initialization of route map. */
3888void
paul94f2b392005-06-28 12:44:16 +00003889bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003890{
3891 route_map_init ();
3892 route_map_init_vty ();
3893 route_map_add_hook (bgp_route_map_update);
3894 route_map_delete_hook (bgp_route_map_update);
3895
paulfee0f4c2004-09-13 05:12:46 +00003896 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003897 route_map_install_match (&route_match_ip_address_cmd);
3898 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003899 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003900 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3901 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003902 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003903 route_map_install_match (&route_match_aspath_cmd);
3904 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003905 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003906 route_map_install_match (&route_match_metric_cmd);
3907 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003908 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003909
3910 route_map_install_set (&route_set_ip_nexthop_cmd);
3911 route_map_install_set (&route_set_local_pref_cmd);
3912 route_map_install_set (&route_set_weight_cmd);
3913 route_map_install_set (&route_set_metric_cmd);
3914 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003915 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003916 route_map_install_set (&route_set_origin_cmd);
3917 route_map_install_set (&route_set_atomic_aggregate_cmd);
3918 route_map_install_set (&route_set_aggregator_as_cmd);
3919 route_map_install_set (&route_set_community_cmd);
3920 route_map_install_set (&route_set_community_delete_cmd);
3921 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3922 route_map_install_set (&route_set_originator_id_cmd);
3923 route_map_install_set (&route_set_ecommunity_rt_cmd);
3924 route_map_install_set (&route_set_ecommunity_soo_cmd);
3925
paulfee0f4c2004-09-13 05:12:46 +00003926 install_element (RMAP_NODE, &match_peer_cmd);
3927 install_element (RMAP_NODE, &match_peer_local_cmd);
3928 install_element (RMAP_NODE, &no_match_peer_cmd);
3929 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3930 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003931 install_element (RMAP_NODE, &match_ip_address_cmd);
3932 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3933 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3934 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3935 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3936 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003937 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3938 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3939 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003940 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3941 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3942 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3943 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3944 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3945 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003946 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3947 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3948 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003949
3950 install_element (RMAP_NODE, &match_aspath_cmd);
3951 install_element (RMAP_NODE, &no_match_aspath_cmd);
3952 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3953 install_element (RMAP_NODE, &match_metric_cmd);
3954 install_element (RMAP_NODE, &no_match_metric_cmd);
3955 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3956 install_element (RMAP_NODE, &match_community_cmd);
3957 install_element (RMAP_NODE, &match_community_exact_cmd);
3958 install_element (RMAP_NODE, &no_match_community_cmd);
3959 install_element (RMAP_NODE, &no_match_community_val_cmd);
3960 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003961 install_element (RMAP_NODE, &match_ecommunity_cmd);
3962 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3963 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003964 install_element (RMAP_NODE, &match_origin_cmd);
3965 install_element (RMAP_NODE, &no_match_origin_cmd);
3966 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003967 install_element (RMAP_NODE, &match_probability_cmd);
3968 install_element (RMAP_NODE, &no_match_probability_cmd);
3969 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003970
3971 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003972 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003973 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3974 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3975 install_element (RMAP_NODE, &set_local_pref_cmd);
3976 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3977 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3978 install_element (RMAP_NODE, &set_weight_cmd);
3979 install_element (RMAP_NODE, &no_set_weight_cmd);
3980 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3981 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003982 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003983 install_element (RMAP_NODE, &no_set_metric_cmd);
3984 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3985 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003986 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003987 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3988 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003989 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3990 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003991 install_element (RMAP_NODE, &set_origin_cmd);
3992 install_element (RMAP_NODE, &no_set_origin_cmd);
3993 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3994 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3995 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3996 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3997 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3998 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3999 install_element (RMAP_NODE, &set_community_cmd);
4000 install_element (RMAP_NODE, &set_community_none_cmd);
4001 install_element (RMAP_NODE, &no_set_community_cmd);
4002 install_element (RMAP_NODE, &no_set_community_val_cmd);
4003 install_element (RMAP_NODE, &no_set_community_none_cmd);
4004 install_element (RMAP_NODE, &set_community_delete_cmd);
4005 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4006 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
4007 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4008 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4009 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4010 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4011 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4012 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4013 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4014 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4015 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4016 install_element (RMAP_NODE, &set_originator_id_cmd);
4017 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4018 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
4019
4020#ifdef HAVE_IPV6
4021 route_map_install_match (&route_match_ipv6_address_cmd);
4022 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4023 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4024 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4025 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004026 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4027
paul718e3742002-12-13 20:15:29 +00004028 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4029 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4030 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4031 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4032 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4033 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4034 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4035 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4036 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4037 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4038 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4039 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004040 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4041 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004042#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00004043
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004044 /* AS-Pathlimit: functionality removed, commands kept for
4045 * compatibility.
4046 */
Paul Jakma41367172007-08-06 15:24:51 +00004047 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4048 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4049 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4050 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4051 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4052 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004053}