blob: c498f584dfc4cddf0c8c98a87f18bd9e56a7bc5a [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{
1177 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001178 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001179 char *endptr = NULL;
1180
1181 if (all_digit (arg))
1182 {
1183 /* set metric value check*/
Ulrich Weber664711c2011-12-21 02:24:11 +04001184 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001185 larg = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001186 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001187 return NULL;
paul94f2b392005-06-28 12:44:16 +00001188 metric = larg;
paul718e3742002-12-13 20:15:29 +00001189 }
1190 else
1191 {
1192 /* set metric +/-value check */
1193 if ((strncmp (arg, "+", 1) != 0
1194 && strncmp (arg, "-", 1) != 0)
1195 || (! all_digit (arg+1)))
1196 return NULL;
1197
Ulrich Weber664711c2011-12-21 02:24:11 +04001198 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001199 larg = strtoul (arg+1, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001200 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001201 return NULL;
paul94f2b392005-06-28 12:44:16 +00001202 metric = larg;
paul718e3742002-12-13 20:15:29 +00001203 }
1204
1205 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1206}
1207
1208/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001209static void
paul718e3742002-12-13 20:15:29 +00001210route_set_metric_free (void *rule)
1211{
1212 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1213}
1214
1215/* Set metric rule structure. */
1216struct route_map_rule_cmd route_set_metric_cmd =
1217{
1218 "metric",
1219 route_set_metric,
1220 route_set_metric_compile,
1221 route_set_metric_free,
1222};
David Lamparter6b0655a2014-06-04 06:53:35 +02001223
paul718e3742002-12-13 20:15:29 +00001224/* `set as-path prepend ASPATH' */
1225
1226/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001227static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001228route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1229{
1230 struct aspath *aspath;
1231 struct aspath *new;
1232 struct bgp_info *binfo;
1233
1234 if (type == RMAP_BGP)
1235 {
1236 aspath = rule;
1237 binfo = object;
1238
1239 if (binfo->attr->aspath->refcnt)
1240 new = aspath_dup (binfo->attr->aspath);
1241 else
1242 new = binfo->attr->aspath;
1243
1244 aspath_prepend (aspath, new);
1245 binfo->attr->aspath = new;
1246 }
1247
1248 return RMAP_OKAY;
1249}
1250
Timo Teräs2aa640b2014-05-20 08:57:26 +03001251/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001252struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1253{
1254 "as-path prepend",
1255 route_set_aspath_prepend,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001256 route_aspath_compile,
1257 route_aspath_free,
paul718e3742002-12-13 20:15:29 +00001258};
David Lamparter6b0655a2014-06-04 06:53:35 +02001259
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001260/* `set as-path exclude ASn' */
1261
1262/* For ASN exclude mechanism.
1263 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1264 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1265 */
1266static route_map_result_t
1267route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1268{
1269 struct aspath * new_path, * exclude_path;
1270 struct bgp_info *binfo;
1271
1272 if (type == RMAP_BGP)
1273 {
1274 exclude_path = rule;
1275 binfo = object;
1276 if (binfo->attr->aspath->refcnt)
1277 new_path = aspath_dup (binfo->attr->aspath);
1278 else
1279 new_path = binfo->attr->aspath;
1280 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1281 }
1282 return RMAP_OKAY;
1283}
1284
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001285/* Set ASn exlude rule structure. */
1286struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1287{
1288 "as-path exclude",
1289 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001290 route_aspath_compile,
1291 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001292};
David Lamparter6b0655a2014-06-04 06:53:35 +02001293
paul718e3742002-12-13 20:15:29 +00001294/* `set community COMMUNITY' */
1295struct rmap_com_set
1296{
1297 struct community *com;
1298 int additive;
1299 int none;
1300};
1301
1302/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001303static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001304route_set_community (void *rule, struct prefix *prefix,
1305 route_map_object_t type, void *object)
1306{
1307 struct rmap_com_set *rcs;
1308 struct bgp_info *binfo;
1309 struct attr *attr;
1310 struct community *new = NULL;
1311 struct community *old;
1312 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001313
paul718e3742002-12-13 20:15:29 +00001314 if (type == RMAP_BGP)
1315 {
1316 rcs = rule;
1317 binfo = object;
1318 attr = binfo->attr;
1319 old = attr->community;
1320
1321 /* "none" case. */
1322 if (rcs->none)
1323 {
1324 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1325 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001326 /* See the longer comment down below. */
1327 if (old && old->refcnt == 0)
1328 community_free(old);
paul718e3742002-12-13 20:15:29 +00001329 return RMAP_OKAY;
1330 }
1331
1332 /* "additive" case. */
1333 if (rcs->additive && old)
1334 {
1335 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001336
1337 /* HACK: if the old community is not intern'd,
1338 * we should free it here, or all reference to it may be lost.
1339 * Really need to cleanup attribute caching sometime.
1340 */
1341 if (old->refcnt == 0)
1342 community_free (old);
paul718e3742002-12-13 20:15:29 +00001343 new = community_uniq_sort (merge);
1344 community_free (merge);
1345 }
1346 else
1347 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001348
1349 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001350 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001351
paul718e3742002-12-13 20:15:29 +00001352 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1353 }
1354
1355 return RMAP_OKAY;
1356}
1357
1358/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001359static void *
paulfd79ac92004-10-13 05:06:08 +00001360route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001361{
1362 struct rmap_com_set *rcs;
1363 struct community *com = NULL;
1364 char *sp;
1365 int additive = 0;
1366 int none = 0;
1367
1368 if (strcmp (arg, "none") == 0)
1369 none = 1;
1370 else
1371 {
1372 sp = strstr (arg, "additive");
1373
1374 if (sp && sp > arg)
1375 {
1376 /* "additive" keyworkd is included. */
1377 additive = 1;
1378 *(sp - 1) = '\0';
1379 }
1380
1381 com = community_str2com (arg);
1382
1383 if (additive)
1384 *(sp - 1) = ' ';
1385
1386 if (! com)
1387 return NULL;
1388 }
1389
Stephen Hemminger393deb92008-08-18 14:13:29 -07001390 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001391 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001392 rcs->additive = additive;
1393 rcs->none = none;
1394
1395 return rcs;
1396}
1397
1398/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001399static void
paul718e3742002-12-13 20:15:29 +00001400route_set_community_free (void *rule)
1401{
1402 struct rmap_com_set *rcs = rule;
1403
1404 if (rcs->com)
1405 community_free (rcs->com);
1406 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1407}
1408
1409/* Set community rule structure. */
1410struct route_map_rule_cmd route_set_community_cmd =
1411{
1412 "community",
1413 route_set_community,
1414 route_set_community_compile,
1415 route_set_community_free,
1416};
David Lamparter6b0655a2014-06-04 06:53:35 +02001417
hassofee6e4e2005-02-02 16:29:31 +00001418/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001419
1420/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001421static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001422route_set_community_delete (void *rule, struct prefix *prefix,
1423 route_map_object_t type, void *object)
1424{
1425 struct community_list *list;
1426 struct community *merge;
1427 struct community *new;
1428 struct community *old;
1429 struct bgp_info *binfo;
1430
1431 if (type == RMAP_BGP)
1432 {
1433 if (! rule)
1434 return RMAP_OKAY;
1435
1436 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001437 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001438 old = binfo->attr->community;
1439
1440 if (list && old)
1441 {
1442 merge = community_list_match_delete (community_dup (old), list);
1443 new = community_uniq_sort (merge);
1444 community_free (merge);
1445
Michael Lambert604a9b42010-09-13 11:48:11 -04001446 /* HACK: if the old community is not intern'd,
1447 * we should free it here, or all reference to it may be lost.
1448 * Really need to cleanup attribute caching sometime.
1449 */
1450 if (old->refcnt == 0)
1451 community_free (old);
1452
paul718e3742002-12-13 20:15:29 +00001453 if (new->size == 0)
1454 {
1455 binfo->attr->community = NULL;
1456 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1457 community_free (new);
1458 }
1459 else
1460 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001461 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001462 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1463 }
1464 }
1465 }
1466
1467 return RMAP_OKAY;
1468}
1469
1470/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001471static void *
paulfd79ac92004-10-13 05:06:08 +00001472route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001473{
1474 char *p;
1475 char *str;
1476 int len;
1477
1478 p = strchr (arg, ' ');
1479 if (p)
1480 {
1481 len = p - arg;
1482 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1483 memcpy (str, arg, len);
1484 }
1485 else
1486 str = NULL;
1487
1488 return str;
1489}
1490
1491/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001492static void
paul718e3742002-12-13 20:15:29 +00001493route_set_community_delete_free (void *rule)
1494{
1495 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1496}
1497
1498/* Set community rule structure. */
1499struct route_map_rule_cmd route_set_community_delete_cmd =
1500{
1501 "comm-list",
1502 route_set_community_delete,
1503 route_set_community_delete_compile,
1504 route_set_community_delete_free,
1505};
David Lamparter6b0655a2014-06-04 06:53:35 +02001506
paul718e3742002-12-13 20:15:29 +00001507/* `set extcommunity rt COMMUNITY' */
1508
David Lamparter73d78ea2014-06-04 00:58:47 +02001509/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001510static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001511route_set_ecommunity (void *rule, struct prefix *prefix,
1512 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001513{
1514 struct ecommunity *ecom;
1515 struct ecommunity *new_ecom;
1516 struct ecommunity *old_ecom;
1517 struct bgp_info *bgp_info;
1518
1519 if (type == RMAP_BGP)
1520 {
1521 ecom = rule;
1522 bgp_info = object;
1523
1524 if (! ecom)
1525 return RMAP_OKAY;
1526
1527 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001528 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001529
1530 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001531 {
1532 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1533
1534 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1535 * ->refcnt = 0 => set by a previous route-map statement */
1536 if (!old_ecom->refcnt)
1537 ecommunity_free (&old_ecom);
1538 }
paul718e3742002-12-13 20:15:29 +00001539 else
1540 new_ecom = ecommunity_dup (ecom);
1541
David Lamparter27bf90a2014-06-04 00:59:01 +02001542 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1543 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001544
paul718e3742002-12-13 20:15:29 +00001545 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1546 }
1547 return RMAP_OKAY;
1548}
1549
1550/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001551static void *
paulfd79ac92004-10-13 05:06:08 +00001552route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001553{
1554 struct ecommunity *ecom;
1555
1556 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1557 if (! ecom)
1558 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001559 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001560}
1561
David Lamparter73d78ea2014-06-04 00:58:47 +02001562/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001563static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001564route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001565{
1566 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001567 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001568}
1569
1570/* Set community rule structure. */
1571struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1572{
1573 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001574 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001575 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001576 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001577};
1578
1579/* `set extcommunity soo COMMUNITY' */
1580
paul718e3742002-12-13 20:15:29 +00001581/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001582static void *
paulfd79ac92004-10-13 05:06:08 +00001583route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001584{
1585 struct ecommunity *ecom;
1586
1587 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1588 if (! ecom)
1589 return NULL;
1590
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001591 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001592}
1593
paul718e3742002-12-13 20:15:29 +00001594/* Set community rule structure. */
1595struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1596{
1597 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001598 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001599 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001600 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001601};
David Lamparter6b0655a2014-06-04 06:53:35 +02001602
paul718e3742002-12-13 20:15:29 +00001603/* `set origin ORIGIN' */
1604
1605/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001606static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001607route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1608{
1609 u_char *origin;
1610 struct bgp_info *bgp_info;
1611
1612 if (type == RMAP_BGP)
1613 {
1614 origin = rule;
1615 bgp_info = object;
1616
1617 bgp_info->attr->origin = *origin;
1618 }
1619
1620 return RMAP_OKAY;
1621}
1622
1623/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001624static void *
paulfd79ac92004-10-13 05:06:08 +00001625route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001626{
1627 u_char *origin;
1628
1629 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1630
1631 if (strcmp (arg, "igp") == 0)
1632 *origin = 0;
1633 else if (strcmp (arg, "egp") == 0)
1634 *origin = 1;
1635 else
1636 *origin = 2;
1637
1638 return origin;
1639}
1640
1641/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001642static void
paul718e3742002-12-13 20:15:29 +00001643route_set_origin_free (void *rule)
1644{
1645 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1646}
1647
Timo Teräs2aa640b2014-05-20 08:57:26 +03001648/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001649struct route_map_rule_cmd route_set_origin_cmd =
1650{
1651 "origin",
1652 route_set_origin,
1653 route_set_origin_compile,
1654 route_set_origin_free,
1655};
David Lamparter6b0655a2014-06-04 06:53:35 +02001656
paul718e3742002-12-13 20:15:29 +00001657/* `set atomic-aggregate' */
1658
1659/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001660static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001661route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1662 route_map_object_t type, void *object)
1663{
1664 struct bgp_info *bgp_info;
1665
1666 if (type == RMAP_BGP)
1667 {
1668 bgp_info = object;
1669 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1670 }
1671
1672 return RMAP_OKAY;
1673}
1674
1675/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001676static void *
paulfd79ac92004-10-13 05:06:08 +00001677route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001678{
1679 return (void *)1;
1680}
1681
1682/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001683static void
paul718e3742002-12-13 20:15:29 +00001684route_set_atomic_aggregate_free (void *rule)
1685{
1686 return;
1687}
1688
1689/* Set atomic aggregate rule structure. */
1690struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1691{
1692 "atomic-aggregate",
1693 route_set_atomic_aggregate,
1694 route_set_atomic_aggregate_compile,
1695 route_set_atomic_aggregate_free,
1696};
David Lamparter6b0655a2014-06-04 06:53:35 +02001697
paul718e3742002-12-13 20:15:29 +00001698/* `set aggregator as AS A.B.C.D' */
1699struct aggregator
1700{
1701 as_t as;
1702 struct in_addr address;
1703};
1704
paul94f2b392005-06-28 12:44:16 +00001705static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001706route_set_aggregator_as (void *rule, struct prefix *prefix,
1707 route_map_object_t type, void *object)
1708{
1709 struct bgp_info *bgp_info;
1710 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001711 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001712
1713 if (type == RMAP_BGP)
1714 {
1715 bgp_info = object;
1716 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001717 ae = bgp_attr_extra_get (bgp_info->attr);
1718
1719 ae->aggregator_as = aggregator->as;
1720 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001721 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1722 }
1723
1724 return RMAP_OKAY;
1725}
1726
paul94f2b392005-06-28 12:44:16 +00001727static void *
paulfd79ac92004-10-13 05:06:08 +00001728route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001729{
1730 struct aggregator *aggregator;
1731 char as[10];
1732 char address[20];
1733
Stephen Hemminger393deb92008-08-18 14:13:29 -07001734 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001735 sscanf (arg, "%s %s", as, address);
1736
1737 aggregator->as = strtoul (as, NULL, 10);
1738 inet_aton (address, &aggregator->address);
1739
1740 return aggregator;
1741}
1742
paul94f2b392005-06-28 12:44:16 +00001743static void
paul718e3742002-12-13 20:15:29 +00001744route_set_aggregator_as_free (void *rule)
1745{
1746 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1747}
1748
1749struct route_map_rule_cmd route_set_aggregator_as_cmd =
1750{
1751 "aggregator as",
1752 route_set_aggregator_as,
1753 route_set_aggregator_as_compile,
1754 route_set_aggregator_as_free,
1755};
David Lamparter6b0655a2014-06-04 06:53:35 +02001756
paul718e3742002-12-13 20:15:29 +00001757#ifdef HAVE_IPV6
1758/* `match ipv6 address IP_ACCESS_LIST' */
1759
paul94f2b392005-06-28 12:44:16 +00001760static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001761route_match_ipv6_address (void *rule, struct prefix *prefix,
1762 route_map_object_t type, void *object)
1763{
1764 struct access_list *alist;
1765
1766 if (type == RMAP_BGP)
1767 {
1768 alist = access_list_lookup (AFI_IP6, (char *) rule);
1769 if (alist == NULL)
1770 return RMAP_NOMATCH;
1771
1772 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1773 RMAP_NOMATCH : RMAP_MATCH);
1774 }
1775 return RMAP_NOMATCH;
1776}
1777
paul94f2b392005-06-28 12:44:16 +00001778static void *
paulfd79ac92004-10-13 05:06:08 +00001779route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001780{
1781 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1782}
1783
paul94f2b392005-06-28 12:44:16 +00001784static void
paul718e3742002-12-13 20:15:29 +00001785route_match_ipv6_address_free (void *rule)
1786{
1787 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1788}
1789
1790/* Route map commands for ip address matching. */
1791struct route_map_rule_cmd route_match_ipv6_address_cmd =
1792{
1793 "ipv6 address",
1794 route_match_ipv6_address,
1795 route_match_ipv6_address_compile,
1796 route_match_ipv6_address_free
1797};
David Lamparter6b0655a2014-06-04 06:53:35 +02001798
paul718e3742002-12-13 20:15:29 +00001799/* `match ipv6 next-hop IP_ADDRESS' */
1800
paul94f2b392005-06-28 12:44:16 +00001801static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001802route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1803 route_map_object_t type, void *object)
1804{
1805 struct in6_addr *addr;
1806 struct bgp_info *bgp_info;
1807
1808 if (type == RMAP_BGP)
1809 {
1810 addr = rule;
1811 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001812
1813 if (!bgp_info->attr->extra)
1814 return RMAP_NOMATCH;
1815
1816 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001817 return RMAP_MATCH;
1818
Paul Jakmafb982c22007-05-04 20:15:47 +00001819 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1820 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001821 return RMAP_MATCH;
1822
1823 return RMAP_NOMATCH;
1824 }
1825
1826 return RMAP_NOMATCH;
1827}
1828
paul94f2b392005-06-28 12:44:16 +00001829static void *
paulfd79ac92004-10-13 05:06:08 +00001830route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001831{
1832 struct in6_addr *address;
1833 int ret;
1834
1835 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1836
1837 ret = inet_pton (AF_INET6, arg, address);
1838 if (!ret)
1839 {
1840 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1841 return NULL;
1842 }
1843
1844 return address;
1845}
1846
paul94f2b392005-06-28 12:44:16 +00001847static void
paul718e3742002-12-13 20:15:29 +00001848route_match_ipv6_next_hop_free (void *rule)
1849{
1850 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1851}
1852
1853struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1854{
1855 "ipv6 next-hop",
1856 route_match_ipv6_next_hop,
1857 route_match_ipv6_next_hop_compile,
1858 route_match_ipv6_next_hop_free
1859};
David Lamparter6b0655a2014-06-04 06:53:35 +02001860
paul718e3742002-12-13 20:15:29 +00001861/* `match ipv6 address prefix-list PREFIX_LIST' */
1862
paul94f2b392005-06-28 12:44:16 +00001863static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001864route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1865 route_map_object_t type, void *object)
1866{
1867 struct prefix_list *plist;
1868
1869 if (type == RMAP_BGP)
1870 {
1871 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1872 if (plist == NULL)
1873 return RMAP_NOMATCH;
1874
1875 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1876 RMAP_NOMATCH : RMAP_MATCH);
1877 }
1878 return RMAP_NOMATCH;
1879}
1880
paul94f2b392005-06-28 12:44:16 +00001881static void *
paulfd79ac92004-10-13 05:06:08 +00001882route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001883{
1884 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1885}
1886
paul94f2b392005-06-28 12:44:16 +00001887static void
paul718e3742002-12-13 20:15:29 +00001888route_match_ipv6_address_prefix_list_free (void *rule)
1889{
1890 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1891}
1892
1893struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1894{
1895 "ipv6 address prefix-list",
1896 route_match_ipv6_address_prefix_list,
1897 route_match_ipv6_address_prefix_list_compile,
1898 route_match_ipv6_address_prefix_list_free
1899};
David Lamparter6b0655a2014-06-04 06:53:35 +02001900
paul718e3742002-12-13 20:15:29 +00001901/* `set ipv6 nexthop global IP_ADDRESS' */
1902
1903/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001904static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001905route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1906 route_map_object_t type, void *object)
1907{
1908 struct in6_addr *address;
1909 struct bgp_info *bgp_info;
1910
1911 if (type == RMAP_BGP)
1912 {
1913 /* Fetch routemap's rule information. */
1914 address = rule;
1915 bgp_info = object;
1916
1917 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001918 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001919
1920 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001921 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1922 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001923 }
1924
1925 return RMAP_OKAY;
1926}
1927
1928/* Route map `ip next-hop' compile function. Given string is converted
1929 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001930static void *
paulfd79ac92004-10-13 05:06:08 +00001931route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001932{
1933 int ret;
1934 struct in6_addr *address;
1935
1936 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1937
1938 ret = inet_pton (AF_INET6, arg, address);
1939
1940 if (ret == 0)
1941 {
1942 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1943 return NULL;
1944 }
1945
1946 return address;
1947}
1948
1949/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001950static void
paul718e3742002-12-13 20:15:29 +00001951route_set_ipv6_nexthop_global_free (void *rule)
1952{
1953 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1954}
1955
1956/* Route map commands for ip nexthop set. */
1957struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1958{
1959 "ipv6 next-hop global",
1960 route_set_ipv6_nexthop_global,
1961 route_set_ipv6_nexthop_global_compile,
1962 route_set_ipv6_nexthop_global_free
1963};
David Lamparter6b0655a2014-06-04 06:53:35 +02001964
paul718e3742002-12-13 20:15:29 +00001965/* `set ipv6 nexthop local IP_ADDRESS' */
1966
1967/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001968static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001969route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1970 route_map_object_t type, void *object)
1971{
1972 struct in6_addr *address;
1973 struct bgp_info *bgp_info;
1974
1975 if (type == RMAP_BGP)
1976 {
1977 /* Fetch routemap's rule information. */
1978 address = rule;
1979 bgp_info = object;
1980
1981 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001982 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001983
1984 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001985 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1986 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001987 }
1988
1989 return RMAP_OKAY;
1990}
1991
1992/* Route map `ip nexthop' compile function. Given string is converted
1993 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001994static void *
paulfd79ac92004-10-13 05:06:08 +00001995route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001996{
1997 int ret;
1998 struct in6_addr *address;
1999
2000 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2001
2002 ret = inet_pton (AF_INET6, arg, address);
2003
2004 if (ret == 0)
2005 {
2006 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2007 return NULL;
2008 }
2009
2010 return address;
2011}
2012
2013/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002014static void
paul718e3742002-12-13 20:15:29 +00002015route_set_ipv6_nexthop_local_free (void *rule)
2016{
2017 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2018}
2019
2020/* Route map commands for ip nexthop set. */
2021struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2022{
2023 "ipv6 next-hop local",
2024 route_set_ipv6_nexthop_local,
2025 route_set_ipv6_nexthop_local_compile,
2026 route_set_ipv6_nexthop_local_free
2027};
2028#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02002029
paul718e3742002-12-13 20:15:29 +00002030/* `set vpnv4 nexthop A.B.C.D' */
2031
paul94f2b392005-06-28 12:44:16 +00002032static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002033route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2034 route_map_object_t type, void *object)
2035{
2036 struct in_addr *address;
2037 struct bgp_info *bgp_info;
2038
2039 if (type == RMAP_BGP)
2040 {
2041 /* Fetch routemap's rule information. */
2042 address = rule;
2043 bgp_info = object;
2044
2045 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002046 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002047 }
2048
2049 return RMAP_OKAY;
2050}
2051
paul94f2b392005-06-28 12:44:16 +00002052static void *
paulfd79ac92004-10-13 05:06:08 +00002053route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002054{
2055 int ret;
2056 struct in_addr *address;
2057
2058 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2059
2060 ret = inet_aton (arg, address);
2061
2062 if (ret == 0)
2063 {
2064 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2065 return NULL;
2066 }
2067
2068 return address;
2069}
2070
paul94f2b392005-06-28 12:44:16 +00002071static void
paul718e3742002-12-13 20:15:29 +00002072route_set_vpnv4_nexthop_free (void *rule)
2073{
2074 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2075}
2076
2077/* Route map commands for ip nexthop set. */
2078struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2079{
2080 "vpnv4 next-hop",
2081 route_set_vpnv4_nexthop,
2082 route_set_vpnv4_nexthop_compile,
2083 route_set_vpnv4_nexthop_free
2084};
David Lamparter6b0655a2014-06-04 06:53:35 +02002085
paul718e3742002-12-13 20:15:29 +00002086/* `set originator-id' */
2087
2088/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002089static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002090route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2091{
2092 struct in_addr *address;
2093 struct bgp_info *bgp_info;
2094
2095 if (type == RMAP_BGP)
2096 {
2097 address = rule;
2098 bgp_info = object;
2099
2100 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002101 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002102 }
2103
2104 return RMAP_OKAY;
2105}
2106
2107/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002108static void *
paulfd79ac92004-10-13 05:06:08 +00002109route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002110{
2111 int ret;
2112 struct in_addr *address;
2113
2114 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2115
2116 ret = inet_aton (arg, address);
2117
2118 if (ret == 0)
2119 {
2120 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2121 return NULL;
2122 }
2123
2124 return address;
2125}
2126
2127/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002128static void
paul718e3742002-12-13 20:15:29 +00002129route_set_originator_id_free (void *rule)
2130{
2131 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2132}
2133
Timo Teräs2aa640b2014-05-20 08:57:26 +03002134/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002135struct route_map_rule_cmd route_set_originator_id_cmd =
2136{
2137 "originator-id",
2138 route_set_originator_id,
2139 route_set_originator_id_compile,
2140 route_set_originator_id_free,
2141};
David Lamparter6b0655a2014-06-04 06:53:35 +02002142
paul718e3742002-12-13 20:15:29 +00002143/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002144static int
paul718e3742002-12-13 20:15:29 +00002145bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002146 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002147{
2148 int ret;
2149
2150 ret = route_map_add_match (index, command, arg);
2151 if (ret)
2152 {
2153 switch (ret)
2154 {
2155 case RMAP_RULE_MISSING:
2156 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2157 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002158 case RMAP_COMPILE_ERROR:
2159 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2160 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002161 }
2162 }
2163 return CMD_SUCCESS;
2164}
2165
2166/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002167static int
paul718e3742002-12-13 20:15:29 +00002168bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002169 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002170{
2171 int ret;
2172
2173 ret = route_map_delete_match (index, command, arg);
2174 if (ret)
2175 {
2176 switch (ret)
2177 {
2178 case RMAP_RULE_MISSING:
2179 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2180 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002181 case RMAP_COMPILE_ERROR:
2182 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2183 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002184 }
2185 }
2186 return CMD_SUCCESS;
2187}
2188
2189/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002190static int
paul718e3742002-12-13 20:15:29 +00002191bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002192 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002193{
2194 int ret;
2195
2196 ret = route_map_add_set (index, command, arg);
2197 if (ret)
2198 {
2199 switch (ret)
2200 {
2201 case RMAP_RULE_MISSING:
2202 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2203 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002204 case RMAP_COMPILE_ERROR:
2205 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2206 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002207 }
2208 }
2209 return CMD_SUCCESS;
2210}
2211
2212/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002213static int
paul718e3742002-12-13 20:15:29 +00002214bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002215 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002216{
2217 int ret;
2218
2219 ret = route_map_delete_set (index, command, arg);
2220 if (ret)
2221 {
2222 switch (ret)
2223 {
2224 case RMAP_RULE_MISSING:
2225 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2226 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002227 case RMAP_COMPILE_ERROR:
2228 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2229 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002230 }
2231 }
2232 return CMD_SUCCESS;
2233}
2234
2235/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002236static void
paulfd79ac92004-10-13 05:06:08 +00002237bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002238{
2239 int i;
2240 afi_t afi;
2241 safi_t safi;
2242 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002243 struct listnode *node, *nnode;
2244 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002245 struct bgp *bgp;
2246 struct peer *peer;
2247 struct peer_group *group;
2248 struct bgp_filter *filter;
2249 struct bgp_node *bn;
2250 struct bgp_static *bgp_static;
2251
2252 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002253 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002254 {
paul1eb8ef22005-04-07 07:30:20 +00002255 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002256 {
2257 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2258 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2259 {
2260 filter = &peer->filter[afi][safi];
2261
paulfee0f4c2004-09-13 05:12:46 +00002262 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002263 {
2264 if (filter->map[direct].name)
2265 filter->map[direct].map =
2266 route_map_lookup_by_name (filter->map[direct].name);
2267 else
2268 filter->map[direct].map = NULL;
2269 }
2270
2271 if (filter->usmap.name)
2272 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2273 else
2274 filter->usmap.map = NULL;
2275 }
2276 }
paul1eb8ef22005-04-07 07:30:20 +00002277 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002278 {
2279 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2280 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2281 {
2282 filter = &group->conf->filter[afi][safi];
2283
paulfee0f4c2004-09-13 05:12:46 +00002284 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002285 {
2286 if (filter->map[direct].name)
2287 filter->map[direct].map =
2288 route_map_lookup_by_name (filter->map[direct].name);
2289 else
2290 filter->map[direct].map = NULL;
2291 }
2292
2293 if (filter->usmap.name)
2294 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2295 else
2296 filter->usmap.map = NULL;
2297 }
2298 }
2299 }
2300
2301 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002302 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002303 {
paul1eb8ef22005-04-07 07:30:20 +00002304 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002305 {
2306 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2307 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2308 {
2309 if (peer->default_rmap[afi][safi].name)
2310 peer->default_rmap[afi][safi].map =
2311 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2312 else
2313 peer->default_rmap[afi][safi].map = NULL;
2314 }
2315 }
2316 }
2317
2318 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002319 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002320 {
2321 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2322 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2323 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2324 bn = bgp_route_next (bn))
2325 if ((bgp_static = bn->info) != NULL)
2326 {
2327 if (bgp_static->rmap.name)
2328 bgp_static->rmap.map =
2329 route_map_lookup_by_name (bgp_static->rmap.name);
2330 else
2331 bgp_static->rmap.map = NULL;
2332 }
2333 }
2334
2335 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002336 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002337 {
2338 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2339 {
2340 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2341 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2342 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2343#ifdef HAVE_IPV6
2344 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2345 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2346 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2347#endif /* HAVE_IPV6 */
2348 }
2349 }
2350}
David Lamparter6b0655a2014-06-04 06:53:35 +02002351
paulfee0f4c2004-09-13 05:12:46 +00002352DEFUN (match_peer,
2353 match_peer_cmd,
2354 "match peer (A.B.C.D|X:X::X:X)",
2355 MATCH_STR
2356 "Match peer address\n"
2357 "IPv6 address of peer\n"
2358 "IP address of peer\n")
2359{
2360 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2361}
2362
2363DEFUN (match_peer_local,
2364 match_peer_local_cmd,
2365 "match peer local",
2366 MATCH_STR
2367 "Match peer address\n"
2368 "Static or Redistributed routes\n")
2369{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002370 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002371}
2372
2373DEFUN (no_match_peer,
2374 no_match_peer_cmd,
2375 "no match peer",
2376 NO_STR
2377 MATCH_STR
2378 "Match peer address\n")
2379{
2380 if (argc == 0)
2381 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2382
2383 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2384}
2385
2386ALIAS (no_match_peer,
2387 no_match_peer_val_cmd,
2388 "no match peer (A.B.C.D|X:X::X:X)",
2389 NO_STR
2390 MATCH_STR
2391 "Match peer address\n"
2392 "IPv6 address of peer\n"
2393 "IP address of peer\n")
2394
2395ALIAS (no_match_peer,
2396 no_match_peer_local_cmd,
2397 "no match peer local",
2398 NO_STR
2399 MATCH_STR
2400 "Match peer address\n"
2401 "Static or Redistributed routes\n")
2402
paul718e3742002-12-13 20:15:29 +00002403DEFUN (match_ip_address,
2404 match_ip_address_cmd,
2405 "match ip address (<1-199>|<1300-2699>|WORD)",
2406 MATCH_STR
2407 IP_STR
2408 "Match address of route\n"
2409 "IP access-list number\n"
2410 "IP access-list number (expanded range)\n"
2411 "IP Access-list name\n")
2412{
2413 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2414}
2415
2416DEFUN (no_match_ip_address,
2417 no_match_ip_address_cmd,
2418 "no match ip address",
2419 NO_STR
2420 MATCH_STR
2421 IP_STR
2422 "Match address of route\n")
2423{
2424 if (argc == 0)
2425 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2426
2427 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2428}
2429
2430ALIAS (no_match_ip_address,
2431 no_match_ip_address_val_cmd,
2432 "no match ip address (<1-199>|<1300-2699>|WORD)",
2433 NO_STR
2434 MATCH_STR
2435 IP_STR
2436 "Match address of route\n"
2437 "IP access-list number\n"
2438 "IP access-list number (expanded range)\n"
2439 "IP Access-list name\n")
2440
2441DEFUN (match_ip_next_hop,
2442 match_ip_next_hop_cmd,
2443 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2444 MATCH_STR
2445 IP_STR
2446 "Match next-hop address of route\n"
2447 "IP access-list number\n"
2448 "IP access-list number (expanded range)\n"
2449 "IP Access-list name\n")
2450{
2451 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2452}
2453
2454DEFUN (no_match_ip_next_hop,
2455 no_match_ip_next_hop_cmd,
2456 "no match ip next-hop",
2457 NO_STR
2458 MATCH_STR
2459 IP_STR
2460 "Match next-hop address of route\n")
2461{
2462 if (argc == 0)
2463 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2464
2465 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2466}
2467
2468ALIAS (no_match_ip_next_hop,
2469 no_match_ip_next_hop_val_cmd,
2470 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2471 NO_STR
2472 MATCH_STR
2473 IP_STR
2474 "Match next-hop address of route\n"
2475 "IP access-list number\n"
2476 "IP access-list number (expanded range)\n"
2477 "IP Access-list name\n")
2478
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002479/* match probability { */
2480
2481DEFUN (match_probability,
2482 match_probability_cmd,
2483 "match probability <0-100>",
2484 MATCH_STR
2485 "Match portion of routes defined by percentage value\n"
2486 "Percentage of routes\n")
2487{
2488 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2489}
2490
2491DEFUN (no_match_probability,
2492 no_match_probability_cmd,
2493 "no match probability",
2494 NO_STR
2495 MATCH_STR
2496 "Match portion of routes defined by percentage value\n")
2497{
2498 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2499}
2500
2501ALIAS (no_match_probability,
2502 no_match_probability_val_cmd,
2503 "no match probability <1-99>",
2504 NO_STR
2505 MATCH_STR
2506 "Match portion of routes defined by percentage value\n"
2507 "Percentage of routes\n")
2508
2509/* } */
2510
hassoc1643bb2005-02-02 16:43:17 +00002511DEFUN (match_ip_route_source,
2512 match_ip_route_source_cmd,
2513 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2514 MATCH_STR
2515 IP_STR
2516 "Match advertising source address of route\n"
2517 "IP access-list number\n"
2518 "IP access-list number (expanded range)\n"
2519 "IP standard access-list name\n")
2520{
2521 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2522}
2523
2524DEFUN (no_match_ip_route_source,
2525 no_match_ip_route_source_cmd,
2526 "no match ip route-source",
2527 NO_STR
2528 MATCH_STR
2529 IP_STR
2530 "Match advertising source address of route\n")
2531{
2532 if (argc == 0)
2533 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2534
2535 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2536}
2537
2538ALIAS (no_match_ip_route_source,
2539 no_match_ip_route_source_val_cmd,
2540 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2541 NO_STR
2542 MATCH_STR
2543 IP_STR
2544 "Match advertising source address of route\n"
2545 "IP access-list number\n"
2546 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002547 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002548
paul718e3742002-12-13 20:15:29 +00002549DEFUN (match_ip_address_prefix_list,
2550 match_ip_address_prefix_list_cmd,
2551 "match ip address prefix-list WORD",
2552 MATCH_STR
2553 IP_STR
2554 "Match address of route\n"
2555 "Match entries of prefix-lists\n"
2556 "IP prefix-list name\n")
2557{
2558 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2559}
2560
2561DEFUN (no_match_ip_address_prefix_list,
2562 no_match_ip_address_prefix_list_cmd,
2563 "no match ip address prefix-list",
2564 NO_STR
2565 MATCH_STR
2566 IP_STR
2567 "Match address of route\n"
2568 "Match entries of prefix-lists\n")
2569{
2570 if (argc == 0)
2571 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2572
2573 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2574}
2575
2576ALIAS (no_match_ip_address_prefix_list,
2577 no_match_ip_address_prefix_list_val_cmd,
2578 "no match ip address prefix-list WORD",
2579 NO_STR
2580 MATCH_STR
2581 IP_STR
2582 "Match address of route\n"
2583 "Match entries of prefix-lists\n"
2584 "IP prefix-list name\n")
2585
2586DEFUN (match_ip_next_hop_prefix_list,
2587 match_ip_next_hop_prefix_list_cmd,
2588 "match ip next-hop prefix-list WORD",
2589 MATCH_STR
2590 IP_STR
2591 "Match next-hop address of route\n"
2592 "Match entries of prefix-lists\n"
2593 "IP prefix-list name\n")
2594{
2595 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2596}
2597
2598DEFUN (no_match_ip_next_hop_prefix_list,
2599 no_match_ip_next_hop_prefix_list_cmd,
2600 "no match ip next-hop prefix-list",
2601 NO_STR
2602 MATCH_STR
2603 IP_STR
2604 "Match next-hop address of route\n"
2605 "Match entries of prefix-lists\n")
2606{
2607 if (argc == 0)
2608 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2609
2610 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2611}
2612
2613ALIAS (no_match_ip_next_hop_prefix_list,
2614 no_match_ip_next_hop_prefix_list_val_cmd,
2615 "no match ip next-hop prefix-list WORD",
2616 NO_STR
2617 MATCH_STR
2618 IP_STR
2619 "Match next-hop address of route\n"
2620 "Match entries of prefix-lists\n"
2621 "IP prefix-list name\n")
2622
hassoc1643bb2005-02-02 16:43:17 +00002623DEFUN (match_ip_route_source_prefix_list,
2624 match_ip_route_source_prefix_list_cmd,
2625 "match ip route-source prefix-list WORD",
2626 MATCH_STR
2627 IP_STR
2628 "Match advertising source address of route\n"
2629 "Match entries of prefix-lists\n"
2630 "IP prefix-list name\n")
2631{
2632 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2633}
2634
2635DEFUN (no_match_ip_route_source_prefix_list,
2636 no_match_ip_route_source_prefix_list_cmd,
2637 "no match ip route-source prefix-list",
2638 NO_STR
2639 MATCH_STR
2640 IP_STR
2641 "Match advertising source address of route\n"
2642 "Match entries of prefix-lists\n")
2643{
2644 if (argc == 0)
2645 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2646
2647 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2648}
2649
2650ALIAS (no_match_ip_route_source_prefix_list,
2651 no_match_ip_route_source_prefix_list_val_cmd,
2652 "no match ip route-source prefix-list WORD",
2653 NO_STR
2654 MATCH_STR
2655 IP_STR
2656 "Match advertising source address of route\n"
2657 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002658 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002659
paul718e3742002-12-13 20:15:29 +00002660DEFUN (match_metric,
2661 match_metric_cmd,
2662 "match metric <0-4294967295>",
2663 MATCH_STR
2664 "Match metric of route\n"
2665 "Metric value\n")
2666{
2667 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2668}
2669
2670DEFUN (no_match_metric,
2671 no_match_metric_cmd,
2672 "no match metric",
2673 NO_STR
2674 MATCH_STR
2675 "Match metric of route\n")
2676{
2677 if (argc == 0)
2678 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2679
2680 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2681}
2682
2683ALIAS (no_match_metric,
2684 no_match_metric_val_cmd,
2685 "no match metric <0-4294967295>",
2686 NO_STR
2687 MATCH_STR
2688 "Match metric of route\n"
2689 "Metric value\n")
2690
2691DEFUN (match_community,
2692 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002693 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002694 MATCH_STR
2695 "Match BGP community list\n"
2696 "Community-list number (standard)\n"
2697 "Community-list number (expanded)\n"
2698 "Community-list name\n")
2699{
2700 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2701}
2702
2703DEFUN (match_community_exact,
2704 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002705 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002706 MATCH_STR
2707 "Match BGP community list\n"
2708 "Community-list number (standard)\n"
2709 "Community-list number (expanded)\n"
2710 "Community-list name\n"
2711 "Do exact matching of communities\n")
2712{
2713 int ret;
2714 char *argstr;
2715
2716 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2717 strlen (argv[0]) + strlen ("exact-match") + 2);
2718
2719 sprintf (argstr, "%s exact-match", argv[0]);
2720
2721 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2722
2723 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2724
2725 return ret;
2726}
2727
2728DEFUN (no_match_community,
2729 no_match_community_cmd,
2730 "no match community",
2731 NO_STR
2732 MATCH_STR
2733 "Match BGP community list\n")
2734{
2735 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2736}
2737
2738ALIAS (no_match_community,
2739 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002740 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002741 NO_STR
2742 MATCH_STR
2743 "Match BGP community list\n"
2744 "Community-list number (standard)\n"
2745 "Community-list number (expanded)\n"
2746 "Community-list name\n")
2747
2748ALIAS (no_match_community,
2749 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002750 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002751 NO_STR
2752 MATCH_STR
2753 "Match BGP community list\n"
2754 "Community-list number (standard)\n"
2755 "Community-list number (expanded)\n"
2756 "Community-list name\n"
2757 "Do exact matching of communities\n")
2758
paul73ffb252003-04-19 15:49:49 +00002759DEFUN (match_ecommunity,
2760 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002761 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002762 MATCH_STR
2763 "Match BGP/VPN extended community list\n"
2764 "Extended community-list number (standard)\n"
2765 "Extended community-list number (expanded)\n"
2766 "Extended community-list name\n")
2767{
2768 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2769}
2770
2771DEFUN (no_match_ecommunity,
2772 no_match_ecommunity_cmd,
2773 "no match extcommunity",
2774 NO_STR
2775 MATCH_STR
2776 "Match BGP/VPN extended community list\n")
2777{
2778 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2779}
2780
2781ALIAS (no_match_ecommunity,
2782 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002783 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002784 NO_STR
2785 MATCH_STR
2786 "Match BGP/VPN extended community list\n"
2787 "Extended community-list number (standard)\n"
2788 "Extended community-list number (expanded)\n"
2789 "Extended community-list name\n")
2790
paul718e3742002-12-13 20:15:29 +00002791DEFUN (match_aspath,
2792 match_aspath_cmd,
2793 "match as-path WORD",
2794 MATCH_STR
2795 "Match BGP AS path list\n"
2796 "AS path access-list name\n")
2797{
2798 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2799}
2800
2801DEFUN (no_match_aspath,
2802 no_match_aspath_cmd,
2803 "no match as-path",
2804 NO_STR
2805 MATCH_STR
2806 "Match BGP AS path list\n")
2807{
2808 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2809}
2810
2811ALIAS (no_match_aspath,
2812 no_match_aspath_val_cmd,
2813 "no match as-path WORD",
2814 NO_STR
2815 MATCH_STR
2816 "Match BGP AS path list\n"
2817 "AS path access-list name\n")
2818
2819DEFUN (match_origin,
2820 match_origin_cmd,
2821 "match origin (egp|igp|incomplete)",
2822 MATCH_STR
2823 "BGP origin code\n"
2824 "remote EGP\n"
2825 "local IGP\n"
2826 "unknown heritage\n")
2827{
2828 if (strncmp (argv[0], "igp", 2) == 0)
2829 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2830 if (strncmp (argv[0], "egp", 1) == 0)
2831 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2832 if (strncmp (argv[0], "incomplete", 2) == 0)
2833 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2834
2835 return CMD_WARNING;
2836}
2837
2838DEFUN (no_match_origin,
2839 no_match_origin_cmd,
2840 "no match origin",
2841 NO_STR
2842 MATCH_STR
2843 "BGP origin code\n")
2844{
2845 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2846}
2847
2848ALIAS (no_match_origin,
2849 no_match_origin_val_cmd,
2850 "no match origin (egp|igp|incomplete)",
2851 NO_STR
2852 MATCH_STR
2853 "BGP origin code\n"
2854 "remote EGP\n"
2855 "local IGP\n"
2856 "unknown heritage\n")
2857
2858DEFUN (set_ip_nexthop,
2859 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002860 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002861 SET_STR
2862 IP_STR
2863 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002864 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002865{
2866 union sockunion su;
2867 int ret;
2868
2869 ret = str2sockunion (argv[0], &su);
2870 if (ret < 0)
2871 {
2872 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2873 return CMD_WARNING;
2874 }
2875
2876 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2877}
2878
paulaf5cd0a2003-11-02 07:24:40 +00002879DEFUN (set_ip_nexthop_peer,
2880 set_ip_nexthop_peer_cmd,
2881 "set ip next-hop peer-address",
2882 SET_STR
2883 IP_STR
2884 "Next hop address\n"
2885 "Use peer address (for BGP only)\n")
2886{
2887 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2888}
2889
paul94f2b392005-06-28 12:44:16 +00002890DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002891 no_set_ip_nexthop_peer_cmd,
2892 "no set ip next-hop peer-address",
2893 NO_STR
2894 SET_STR
2895 IP_STR
2896 "Next hop address\n"
2897 "Use peer address (for BGP only)\n")
2898{
2899 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2900}
2901
2902
paul718e3742002-12-13 20:15:29 +00002903DEFUN (no_set_ip_nexthop,
2904 no_set_ip_nexthop_cmd,
2905 "no set ip next-hop",
2906 NO_STR
2907 SET_STR
paul718e3742002-12-13 20:15:29 +00002908 "Next hop address\n")
2909{
paulaf5cd0a2003-11-02 07:24:40 +00002910 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002911 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2912
2913 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2914}
2915
2916ALIAS (no_set_ip_nexthop,
2917 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002918 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002919 NO_STR
2920 SET_STR
2921 IP_STR
2922 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002923 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002924
2925DEFUN (set_metric,
2926 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002927 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002928 SET_STR
2929 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002930 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002931{
2932 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2933}
2934
paul73ffb252003-04-19 15:49:49 +00002935ALIAS (set_metric,
2936 set_metric_addsub_cmd,
2937 "set metric <+/-metric>",
2938 SET_STR
2939 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002940 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002941
paul718e3742002-12-13 20:15:29 +00002942DEFUN (no_set_metric,
2943 no_set_metric_cmd,
2944 "no set metric",
2945 NO_STR
2946 SET_STR
2947 "Metric value for destination routing protocol\n")
2948{
2949 if (argc == 0)
2950 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2951
2952 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2953}
2954
2955ALIAS (no_set_metric,
2956 no_set_metric_val_cmd,
2957 "no set metric <0-4294967295>",
2958 NO_STR
2959 SET_STR
2960 "Metric value for destination routing protocol\n"
2961 "Metric value\n")
2962
2963DEFUN (set_local_pref,
2964 set_local_pref_cmd,
2965 "set local-preference <0-4294967295>",
2966 SET_STR
2967 "BGP local preference path attribute\n"
2968 "Preference value\n")
2969{
2970 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2971}
2972
2973DEFUN (no_set_local_pref,
2974 no_set_local_pref_cmd,
2975 "no set local-preference",
2976 NO_STR
2977 SET_STR
2978 "BGP local preference path attribute\n")
2979{
2980 if (argc == 0)
2981 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2982
2983 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2984}
2985
2986ALIAS (no_set_local_pref,
2987 no_set_local_pref_val_cmd,
2988 "no set local-preference <0-4294967295>",
2989 NO_STR
2990 SET_STR
2991 "BGP local preference path attribute\n"
2992 "Preference value\n")
2993
2994DEFUN (set_weight,
2995 set_weight_cmd,
2996 "set weight <0-4294967295>",
2997 SET_STR
2998 "BGP weight for routing table\n"
2999 "Weight value\n")
3000{
3001 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3002}
3003
3004DEFUN (no_set_weight,
3005 no_set_weight_cmd,
3006 "no set weight",
3007 NO_STR
3008 SET_STR
3009 "BGP weight for routing table\n")
3010{
3011 if (argc == 0)
3012 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3013
3014 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3015}
3016
3017ALIAS (no_set_weight,
3018 no_set_weight_val_cmd,
3019 "no set weight <0-4294967295>",
3020 NO_STR
3021 SET_STR
3022 "BGP weight for routing table\n"
3023 "Weight value\n")
3024
3025DEFUN (set_aspath_prepend,
3026 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003027 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003028 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003029 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003030 "Prepend to the as-path\n"
3031 "AS number\n")
3032{
3033 int ret;
3034 char *str;
3035
3036 str = argv_concat (argv, argc, 0);
3037 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3038 XFREE (MTYPE_TMP, str);
3039
3040 return ret;
3041}
3042
3043DEFUN (no_set_aspath_prepend,
3044 no_set_aspath_prepend_cmd,
3045 "no set as-path prepend",
3046 NO_STR
3047 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003048 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003049 "Prepend to the as-path\n")
3050{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003051 int ret;
3052 char *str;
3053
3054 if (argc == 0)
3055 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3056
3057 str = argv_concat (argv, argc, 0);
3058 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3059 XFREE (MTYPE_TMP, str);
3060 return ret;
paul718e3742002-12-13 20:15:29 +00003061}
3062
3063ALIAS (no_set_aspath_prepend,
3064 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003065 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003066 NO_STR
3067 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003068 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003069 "Prepend to the as-path\n"
3070 "AS number\n")
3071
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003072DEFUN (set_aspath_exclude,
3073 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003074 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003075 SET_STR
3076 "Transform BGP AS-path attribute\n"
3077 "Exclude from the as-path\n"
3078 "AS number\n")
3079{
3080 int ret;
3081 char *str;
3082
3083 str = argv_concat (argv, argc, 0);
3084 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3085 XFREE (MTYPE_TMP, str);
3086 return ret;
3087}
3088
3089DEFUN (no_set_aspath_exclude,
3090 no_set_aspath_exclude_cmd,
3091 "no set as-path exclude",
3092 NO_STR
3093 SET_STR
3094 "Transform BGP AS_PATH attribute\n"
3095 "Exclude from the as-path\n")
3096{
3097 int ret;
3098 char *str;
3099
3100 if (argc == 0)
3101 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3102
3103 str = argv_concat (argv, argc, 0);
3104 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3105 XFREE (MTYPE_TMP, str);
3106 return ret;
3107}
3108
3109ALIAS (no_set_aspath_exclude,
3110 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003111 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003112 NO_STR
3113 SET_STR
3114 "Transform BGP AS_PATH attribute\n"
3115 "Exclude from the as-path\n"
3116 "AS number\n")
3117
paul718e3742002-12-13 20:15:29 +00003118DEFUN (set_community,
3119 set_community_cmd,
3120 "set community .AA:NN",
3121 SET_STR
3122 "BGP community attribute\n"
3123 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3124{
3125 int i;
3126 int first = 0;
3127 int additive = 0;
3128 struct buffer *b;
3129 struct community *com = NULL;
3130 char *str;
3131 char *argstr;
3132 int ret;
3133
3134 b = buffer_new (1024);
3135
3136 for (i = 0; i < argc; i++)
3137 {
3138 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3139 {
3140 additive = 1;
3141 continue;
3142 }
3143
3144 if (first)
3145 buffer_putc (b, ' ');
3146 else
3147 first = 1;
3148
3149 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3150 {
3151 buffer_putstr (b, "internet");
3152 continue;
3153 }
3154 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3155 {
3156 buffer_putstr (b, "local-AS");
3157 continue;
3158 }
3159 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3160 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3161 {
3162 buffer_putstr (b, "no-advertise");
3163 continue;
3164 }
3165 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3166 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3167 {
3168 buffer_putstr (b, "no-export");
3169 continue;
3170 }
3171 buffer_putstr (b, argv[i]);
3172 }
3173 buffer_putc (b, '\0');
3174
3175 /* Fetch result string then compile it to communities attribute. */
3176 str = buffer_getstr (b);
3177 buffer_free (b);
3178
3179 if (str)
3180 {
3181 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003182 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003183 }
3184
3185 /* Can't compile user input into communities attribute. */
3186 if (! com)
3187 {
3188 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3189 return CMD_WARNING;
3190 }
3191
3192 /* Set communites attribute string. */
3193 str = community_str (com);
3194
3195 if (additive)
3196 {
3197 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3198 strcpy (argstr, str);
3199 strcpy (argstr + strlen (str), " additive");
3200 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3201 XFREE (MTYPE_TMP, argstr);
3202 }
3203 else
3204 ret = bgp_route_set_add (vty, vty->index, "community", str);
3205
3206 community_free (com);
3207
3208 return ret;
3209}
3210
3211DEFUN (set_community_none,
3212 set_community_none_cmd,
3213 "set community none",
3214 SET_STR
3215 "BGP community attribute\n"
3216 "No community attribute\n")
3217{
3218 return bgp_route_set_add (vty, vty->index, "community", "none");
3219}
3220
3221DEFUN (no_set_community,
3222 no_set_community_cmd,
3223 "no set community",
3224 NO_STR
3225 SET_STR
3226 "BGP community attribute\n")
3227{
3228 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3229}
3230
3231ALIAS (no_set_community,
3232 no_set_community_val_cmd,
3233 "no set community .AA:NN",
3234 NO_STR
3235 SET_STR
3236 "BGP community attribute\n"
3237 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3238
3239ALIAS (no_set_community,
3240 no_set_community_none_cmd,
3241 "no set community none",
3242 NO_STR
3243 SET_STR
3244 "BGP community attribute\n"
3245 "No community attribute\n")
3246
3247DEFUN (set_community_delete,
3248 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003249 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003250 SET_STR
3251 "set BGP community list (for deletion)\n"
3252 "Community-list number (standard)\n"
3253 "Communitly-list number (expanded)\n"
3254 "Community-list name\n"
3255 "Delete matching communities\n")
3256{
3257 char *str;
3258
3259 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3260 strcpy (str, argv[0]);
3261 strcpy (str + strlen (argv[0]), " delete");
3262
3263 bgp_route_set_add (vty, vty->index, "comm-list", str);
3264
3265 XFREE (MTYPE_TMP, str);
3266 return CMD_SUCCESS;
3267}
3268
3269DEFUN (no_set_community_delete,
3270 no_set_community_delete_cmd,
3271 "no set comm-list",
3272 NO_STR
3273 SET_STR
3274 "set BGP community list (for deletion)\n")
3275{
3276 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3277}
3278
3279ALIAS (no_set_community_delete,
3280 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003281 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003282 NO_STR
3283 SET_STR
3284 "set BGP community list (for deletion)\n"
3285 "Community-list number (standard)\n"
3286 "Communitly-list number (expanded)\n"
3287 "Community-list name\n"
3288 "Delete matching communities\n")
3289
3290DEFUN (set_ecommunity_rt,
3291 set_ecommunity_rt_cmd,
3292 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3293 SET_STR
3294 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003295 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003296 "VPN extended community\n")
3297{
3298 int ret;
3299 char *str;
3300
3301 str = argv_concat (argv, argc, 0);
3302 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3303 XFREE (MTYPE_TMP, str);
3304
3305 return ret;
3306}
3307
3308DEFUN (no_set_ecommunity_rt,
3309 no_set_ecommunity_rt_cmd,
3310 "no set extcommunity rt",
3311 NO_STR
3312 SET_STR
3313 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003314 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003315{
3316 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3317}
3318
3319ALIAS (no_set_ecommunity_rt,
3320 no_set_ecommunity_rt_val_cmd,
3321 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3322 NO_STR
3323 SET_STR
3324 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003325 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003326 "VPN extended community\n")
3327
3328DEFUN (set_ecommunity_soo,
3329 set_ecommunity_soo_cmd,
3330 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3331 SET_STR
3332 "BGP extended community attribute\n"
3333 "Site-of-Origin extended community\n"
3334 "VPN extended community\n")
3335{
3336 int ret;
3337 char *str;
3338
3339 str = argv_concat (argv, argc, 0);
3340 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3341 XFREE (MTYPE_TMP, str);
3342 return ret;
3343}
3344
3345DEFUN (no_set_ecommunity_soo,
3346 no_set_ecommunity_soo_cmd,
3347 "no set extcommunity soo",
3348 NO_STR
3349 SET_STR
3350 "BGP extended community attribute\n"
3351 "Site-of-Origin extended community\n")
3352{
3353 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3354}
3355
3356ALIAS (no_set_ecommunity_soo,
3357 no_set_ecommunity_soo_val_cmd,
3358 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3359 NO_STR
3360 SET_STR
3361 "BGP extended community attribute\n"
3362 "Site-of-Origin extended community\n"
3363 "VPN extended community\n")
3364
3365DEFUN (set_origin,
3366 set_origin_cmd,
3367 "set origin (egp|igp|incomplete)",
3368 SET_STR
3369 "BGP origin code\n"
3370 "remote EGP\n"
3371 "local IGP\n"
3372 "unknown heritage\n")
3373{
3374 if (strncmp (argv[0], "igp", 2) == 0)
3375 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3376 if (strncmp (argv[0], "egp", 1) == 0)
3377 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3378 if (strncmp (argv[0], "incomplete", 2) == 0)
3379 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3380
3381 return CMD_WARNING;
3382}
3383
3384DEFUN (no_set_origin,
3385 no_set_origin_cmd,
3386 "no set origin",
3387 NO_STR
3388 SET_STR
3389 "BGP origin code\n")
3390{
3391 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3392}
3393
3394ALIAS (no_set_origin,
3395 no_set_origin_val_cmd,
3396 "no set origin (egp|igp|incomplete)",
3397 NO_STR
3398 SET_STR
3399 "BGP origin code\n"
3400 "remote EGP\n"
3401 "local IGP\n"
3402 "unknown heritage\n")
3403
3404DEFUN (set_atomic_aggregate,
3405 set_atomic_aggregate_cmd,
3406 "set atomic-aggregate",
3407 SET_STR
3408 "BGP atomic aggregate attribute\n" )
3409{
3410 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3411}
3412
3413DEFUN (no_set_atomic_aggregate,
3414 no_set_atomic_aggregate_cmd,
3415 "no set atomic-aggregate",
3416 NO_STR
3417 SET_STR
3418 "BGP atomic aggregate attribute\n" )
3419{
3420 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3421}
3422
3423DEFUN (set_aggregator_as,
3424 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003425 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003426 SET_STR
3427 "BGP aggregator attribute\n"
3428 "AS number of aggregator\n"
3429 "AS number\n"
3430 "IP address of aggregator\n")
3431{
3432 int ret;
3433 as_t as;
3434 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003435 char *argstr;
3436
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003437 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003438
paul718e3742002-12-13 20:15:29 +00003439 ret = inet_aton (argv[1], &address);
3440 if (ret == 0)
3441 {
3442 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3443 return CMD_WARNING;
3444 }
3445
3446 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3447 strlen (argv[0]) + strlen (argv[1]) + 2);
3448
3449 sprintf (argstr, "%s %s", argv[0], argv[1]);
3450
3451 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3452
3453 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3454
3455 return ret;
3456}
3457
3458DEFUN (no_set_aggregator_as,
3459 no_set_aggregator_as_cmd,
3460 "no set aggregator as",
3461 NO_STR
3462 SET_STR
3463 "BGP aggregator attribute\n"
3464 "AS number of aggregator\n")
3465{
3466 int ret;
3467 as_t as;
3468 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003469 char *argstr;
3470
3471 if (argv == 0)
3472 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3473
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003474 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003475
3476 ret = inet_aton (argv[1], &address);
3477 if (ret == 0)
3478 {
3479 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3480 return CMD_WARNING;
3481 }
3482
3483 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3484 strlen (argv[0]) + strlen (argv[1]) + 2);
3485
3486 sprintf (argstr, "%s %s", argv[0], argv[1]);
3487
3488 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3489
3490 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3491
3492 return ret;
3493}
3494
3495ALIAS (no_set_aggregator_as,
3496 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003497 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003498 NO_STR
3499 SET_STR
3500 "BGP aggregator attribute\n"
3501 "AS number of aggregator\n"
3502 "AS number\n"
3503 "IP address of aggregator\n")
3504
David Lamparter6b0655a2014-06-04 06:53:35 +02003505
paul718e3742002-12-13 20:15:29 +00003506#ifdef HAVE_IPV6
3507DEFUN (match_ipv6_address,
3508 match_ipv6_address_cmd,
3509 "match ipv6 address WORD",
3510 MATCH_STR
3511 IPV6_STR
3512 "Match IPv6 address of route\n"
3513 "IPv6 access-list name\n")
3514{
3515 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3516}
3517
3518DEFUN (no_match_ipv6_address,
3519 no_match_ipv6_address_cmd,
3520 "no match ipv6 address WORD",
3521 NO_STR
3522 MATCH_STR
3523 IPV6_STR
3524 "Match IPv6 address of route\n"
3525 "IPv6 access-list name\n")
3526{
3527 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3528}
3529
3530DEFUN (match_ipv6_next_hop,
3531 match_ipv6_next_hop_cmd,
3532 "match ipv6 next-hop X:X::X:X",
3533 MATCH_STR
3534 IPV6_STR
3535 "Match IPv6 next-hop address of route\n"
3536 "IPv6 address of next hop\n")
3537{
3538 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3539}
3540
3541DEFUN (no_match_ipv6_next_hop,
3542 no_match_ipv6_next_hop_cmd,
3543 "no match ipv6 next-hop X:X::X:X",
3544 NO_STR
3545 MATCH_STR
3546 IPV6_STR
3547 "Match IPv6 next-hop address of route\n"
3548 "IPv6 address of next hop\n")
3549{
3550 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3551}
3552
3553DEFUN (match_ipv6_address_prefix_list,
3554 match_ipv6_address_prefix_list_cmd,
3555 "match ipv6 address prefix-list WORD",
3556 MATCH_STR
3557 IPV6_STR
3558 "Match address of route\n"
3559 "Match entries of prefix-lists\n"
3560 "IP prefix-list name\n")
3561{
3562 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3563}
3564
3565DEFUN (no_match_ipv6_address_prefix_list,
3566 no_match_ipv6_address_prefix_list_cmd,
3567 "no match ipv6 address prefix-list WORD",
3568 NO_STR
3569 MATCH_STR
3570 IPV6_STR
3571 "Match address of route\n"
3572 "Match entries of prefix-lists\n"
3573 "IP prefix-list name\n")
3574{
3575 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3576}
3577
3578DEFUN (set_ipv6_nexthop_global,
3579 set_ipv6_nexthop_global_cmd,
3580 "set ipv6 next-hop global X:X::X:X",
3581 SET_STR
3582 IPV6_STR
3583 "IPv6 next-hop address\n"
3584 "IPv6 global address\n"
3585 "IPv6 address of next hop\n")
3586{
3587 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3588}
3589
3590DEFUN (no_set_ipv6_nexthop_global,
3591 no_set_ipv6_nexthop_global_cmd,
3592 "no set ipv6 next-hop global",
3593 NO_STR
3594 SET_STR
3595 IPV6_STR
3596 "IPv6 next-hop address\n"
3597 "IPv6 global address\n")
3598{
3599 if (argc == 0)
3600 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3601
3602 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3603}
3604
3605ALIAS (no_set_ipv6_nexthop_global,
3606 no_set_ipv6_nexthop_global_val_cmd,
3607 "no set ipv6 next-hop global X:X::X:X",
3608 NO_STR
3609 SET_STR
3610 IPV6_STR
3611 "IPv6 next-hop address\n"
3612 "IPv6 global address\n"
3613 "IPv6 address of next hop\n")
3614
3615DEFUN (set_ipv6_nexthop_local,
3616 set_ipv6_nexthop_local_cmd,
3617 "set ipv6 next-hop local X:X::X:X",
3618 SET_STR
3619 IPV6_STR
3620 "IPv6 next-hop address\n"
3621 "IPv6 local address\n"
3622 "IPv6 address of next hop\n")
3623{
3624 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3625}
3626
3627DEFUN (no_set_ipv6_nexthop_local,
3628 no_set_ipv6_nexthop_local_cmd,
3629 "no set ipv6 next-hop local",
3630 NO_STR
3631 SET_STR
3632 IPV6_STR
3633 "IPv6 next-hop address\n"
3634 "IPv6 local address\n")
3635{
3636 if (argc == 0)
3637 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3638
3639 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3640}
3641
3642ALIAS (no_set_ipv6_nexthop_local,
3643 no_set_ipv6_nexthop_local_val_cmd,
3644 "no set ipv6 next-hop local X:X::X:X",
3645 NO_STR
3646 SET_STR
3647 IPV6_STR
3648 "IPv6 next-hop address\n"
3649 "IPv6 local address\n"
3650 "IPv6 address of next hop\n")
3651#endif /* HAVE_IPV6 */
3652
3653DEFUN (set_vpnv4_nexthop,
3654 set_vpnv4_nexthop_cmd,
3655 "set vpnv4 next-hop A.B.C.D",
3656 SET_STR
3657 "VPNv4 information\n"
3658 "VPNv4 next-hop address\n"
3659 "IP address of next hop\n")
3660{
3661 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3662}
3663
3664DEFUN (no_set_vpnv4_nexthop,
3665 no_set_vpnv4_nexthop_cmd,
3666 "no set vpnv4 next-hop",
3667 NO_STR
3668 SET_STR
3669 "VPNv4 information\n"
3670 "VPNv4 next-hop address\n")
3671{
3672 if (argc == 0)
3673 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3674
3675 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3676}
3677
3678ALIAS (no_set_vpnv4_nexthop,
3679 no_set_vpnv4_nexthop_val_cmd,
3680 "no set vpnv4 next-hop A.B.C.D",
3681 NO_STR
3682 SET_STR
3683 "VPNv4 information\n"
3684 "VPNv4 next-hop address\n"
3685 "IP address of next hop\n")
3686
3687DEFUN (set_originator_id,
3688 set_originator_id_cmd,
3689 "set originator-id A.B.C.D",
3690 SET_STR
3691 "BGP originator ID attribute\n"
3692 "IP address of originator\n")
3693{
3694 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3695}
3696
3697DEFUN (no_set_originator_id,
3698 no_set_originator_id_cmd,
3699 "no set originator-id",
3700 NO_STR
3701 SET_STR
3702 "BGP originator ID attribute\n")
3703{
3704 if (argc == 0)
3705 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3706
3707 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3708}
3709
3710ALIAS (no_set_originator_id,
3711 no_set_originator_id_val_cmd,
3712 "no set originator-id A.B.C.D",
3713 NO_STR
3714 SET_STR
3715 "BGP originator ID attribute\n"
3716 "IP address of originator\n")
3717
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003718DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003719 set_pathlimit_ttl_cmd,
3720 "set pathlimit ttl <1-255>",
3721 SET_STR
3722 "BGP AS-Pathlimit attribute\n"
3723 "Set AS-Path Hop-count TTL\n")
3724{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003725 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003726}
3727
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003728DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003729 no_set_pathlimit_ttl_cmd,
3730 "no set pathlimit ttl",
3731 NO_STR
3732 SET_STR
3733 "BGP AS-Pathlimit attribute\n"
3734 "Set AS-Path Hop-count TTL\n")
3735{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003736 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003737}
3738
3739ALIAS (no_set_pathlimit_ttl,
3740 no_set_pathlimit_ttl_val_cmd,
3741 "no set pathlimit ttl <1-255>",
3742 NO_STR
3743 MATCH_STR
3744 "BGP AS-Pathlimit attribute\n"
3745 "Set AS-Path Hop-count TTL\n")
3746
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003747DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003748 match_pathlimit_as_cmd,
3749 "match pathlimit as <1-65535>",
3750 MATCH_STR
3751 "BGP AS-Pathlimit attribute\n"
3752 "Match Pathlimit AS number\n")
3753{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003754 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003755}
3756
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003757DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003758 no_match_pathlimit_as_cmd,
3759 "no match pathlimit as",
3760 NO_STR
3761 MATCH_STR
3762 "BGP AS-Pathlimit attribute\n"
3763 "Match Pathlimit AS number\n")
3764{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003765 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003766}
3767
3768ALIAS (no_match_pathlimit_as,
3769 no_match_pathlimit_as_val_cmd,
3770 "no match pathlimit as <1-65535>",
3771 NO_STR
3772 MATCH_STR
3773 "BGP AS-Pathlimit attribute\n"
3774 "Match Pathlimit ASN\n")
3775
David Lamparter6b0655a2014-06-04 06:53:35 +02003776
paul718e3742002-12-13 20:15:29 +00003777/* Initialization of route map. */
3778void
paul94f2b392005-06-28 12:44:16 +00003779bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003780{
3781 route_map_init ();
3782 route_map_init_vty ();
3783 route_map_add_hook (bgp_route_map_update);
3784 route_map_delete_hook (bgp_route_map_update);
3785
paulfee0f4c2004-09-13 05:12:46 +00003786 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003787 route_map_install_match (&route_match_ip_address_cmd);
3788 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003789 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003790 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3791 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003792 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003793 route_map_install_match (&route_match_aspath_cmd);
3794 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003795 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003796 route_map_install_match (&route_match_metric_cmd);
3797 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003798 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003799
3800 route_map_install_set (&route_set_ip_nexthop_cmd);
3801 route_map_install_set (&route_set_local_pref_cmd);
3802 route_map_install_set (&route_set_weight_cmd);
3803 route_map_install_set (&route_set_metric_cmd);
3804 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003805 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003806 route_map_install_set (&route_set_origin_cmd);
3807 route_map_install_set (&route_set_atomic_aggregate_cmd);
3808 route_map_install_set (&route_set_aggregator_as_cmd);
3809 route_map_install_set (&route_set_community_cmd);
3810 route_map_install_set (&route_set_community_delete_cmd);
3811 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3812 route_map_install_set (&route_set_originator_id_cmd);
3813 route_map_install_set (&route_set_ecommunity_rt_cmd);
3814 route_map_install_set (&route_set_ecommunity_soo_cmd);
3815
paulfee0f4c2004-09-13 05:12:46 +00003816 install_element (RMAP_NODE, &match_peer_cmd);
3817 install_element (RMAP_NODE, &match_peer_local_cmd);
3818 install_element (RMAP_NODE, &no_match_peer_cmd);
3819 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3820 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003821 install_element (RMAP_NODE, &match_ip_address_cmd);
3822 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3823 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3824 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3825 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3826 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003827 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3828 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3829 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003830 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3831 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3832 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3833 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3834 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3835 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003836 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3837 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3838 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003839
3840 install_element (RMAP_NODE, &match_aspath_cmd);
3841 install_element (RMAP_NODE, &no_match_aspath_cmd);
3842 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3843 install_element (RMAP_NODE, &match_metric_cmd);
3844 install_element (RMAP_NODE, &no_match_metric_cmd);
3845 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3846 install_element (RMAP_NODE, &match_community_cmd);
3847 install_element (RMAP_NODE, &match_community_exact_cmd);
3848 install_element (RMAP_NODE, &no_match_community_cmd);
3849 install_element (RMAP_NODE, &no_match_community_val_cmd);
3850 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003851 install_element (RMAP_NODE, &match_ecommunity_cmd);
3852 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3853 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003854 install_element (RMAP_NODE, &match_origin_cmd);
3855 install_element (RMAP_NODE, &no_match_origin_cmd);
3856 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003857 install_element (RMAP_NODE, &match_probability_cmd);
3858 install_element (RMAP_NODE, &no_match_probability_cmd);
3859 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003860
3861 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003862 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003863 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3864 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3865 install_element (RMAP_NODE, &set_local_pref_cmd);
3866 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3867 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3868 install_element (RMAP_NODE, &set_weight_cmd);
3869 install_element (RMAP_NODE, &no_set_weight_cmd);
3870 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3871 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003872 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003873 install_element (RMAP_NODE, &no_set_metric_cmd);
3874 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3875 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003876 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003877 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3878 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003879 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3880 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003881 install_element (RMAP_NODE, &set_origin_cmd);
3882 install_element (RMAP_NODE, &no_set_origin_cmd);
3883 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3884 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3885 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3886 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3887 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3888 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3889 install_element (RMAP_NODE, &set_community_cmd);
3890 install_element (RMAP_NODE, &set_community_none_cmd);
3891 install_element (RMAP_NODE, &no_set_community_cmd);
3892 install_element (RMAP_NODE, &no_set_community_val_cmd);
3893 install_element (RMAP_NODE, &no_set_community_none_cmd);
3894 install_element (RMAP_NODE, &set_community_delete_cmd);
3895 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3896 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3897 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3898 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3899 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3900 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3901 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3902 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3903 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3904 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3905 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3906 install_element (RMAP_NODE, &set_originator_id_cmd);
3907 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3908 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3909
3910#ifdef HAVE_IPV6
3911 route_map_install_match (&route_match_ipv6_address_cmd);
3912 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3913 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3914 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3915 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003916
paul718e3742002-12-13 20:15:29 +00003917 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3918 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3919 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3920 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3921 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3922 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3923 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3924 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3925 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3926 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3927 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3928 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3929#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003930
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003931 /* AS-Pathlimit: functionality removed, commands kept for
3932 * compatibility.
3933 */
Paul Jakma41367172007-08-06 15:24:51 +00003934 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3935 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3936 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3937 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3938 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3939 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003940}