blob: a0b1fb422ee30e1386c0ca213056b6eccb634603 [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
1509/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001510static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001511route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1512 route_map_object_t type, void *object)
1513{
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)
1531 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1532 else
1533 new_ecom = ecommunity_dup (ecom);
1534
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001535 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
paul718e3742002-12-13 20:15:29 +00001536
hasso70601e02005-05-27 03:26:57 +00001537 if (old_ecom)
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001538 ecommunity_unintern (&old_ecom);
hasso70601e02005-05-27 03:26:57 +00001539
paul718e3742002-12-13 20:15:29 +00001540 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1541 }
1542 return RMAP_OKAY;
1543}
1544
1545/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001546static void *
paulfd79ac92004-10-13 05:06:08 +00001547route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001548{
1549 struct ecommunity *ecom;
1550
1551 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1552 if (! ecom)
1553 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001554 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001555}
1556
1557/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001558static void
paul718e3742002-12-13 20:15:29 +00001559route_set_ecommunity_rt_free (void *rule)
1560{
1561 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001562 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001563}
1564
1565/* Set community rule structure. */
1566struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1567{
1568 "extcommunity rt",
1569 route_set_ecommunity_rt,
1570 route_set_ecommunity_rt_compile,
1571 route_set_ecommunity_rt_free,
1572};
1573
1574/* `set extcommunity soo COMMUNITY' */
1575
1576/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001577static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001578route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1579 route_map_object_t type, void *object)
1580{
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001581 struct ecommunity *ecom, *old_ecom, *new_ecom;
paul718e3742002-12-13 20:15:29 +00001582 struct bgp_info *bgp_info;
1583
1584 if (type == RMAP_BGP)
1585 {
1586 ecom = rule;
1587 bgp_info = object;
1588
1589 if (! ecom)
1590 return RMAP_OKAY;
1591
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001592 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1593
1594 if (old_ecom)
1595 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1596 else
1597 new_ecom = ecommunity_dup (ecom);
1598
1599 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1600
1601 if (old_ecom)
1602 ecommunity_unintern (&old_ecom);
1603
paul718e3742002-12-13 20:15:29 +00001604 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
paul718e3742002-12-13 20:15:29 +00001605 }
1606 return RMAP_OKAY;
1607}
1608
1609/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001610static void *
paulfd79ac92004-10-13 05:06:08 +00001611route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001612{
1613 struct ecommunity *ecom;
1614
1615 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1616 if (! ecom)
1617 return NULL;
1618
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001619 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001620}
1621
1622/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001623static void
paul718e3742002-12-13 20:15:29 +00001624route_set_ecommunity_soo_free (void *rule)
1625{
1626 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001627 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001628}
1629
1630/* Set community rule structure. */
1631struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1632{
1633 "extcommunity soo",
1634 route_set_ecommunity_soo,
1635 route_set_ecommunity_soo_compile,
1636 route_set_ecommunity_soo_free,
1637};
David Lamparter6b0655a2014-06-04 06:53:35 +02001638
paul718e3742002-12-13 20:15:29 +00001639/* `set origin ORIGIN' */
1640
1641/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001642static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001643route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1644{
1645 u_char *origin;
1646 struct bgp_info *bgp_info;
1647
1648 if (type == RMAP_BGP)
1649 {
1650 origin = rule;
1651 bgp_info = object;
1652
1653 bgp_info->attr->origin = *origin;
1654 }
1655
1656 return RMAP_OKAY;
1657}
1658
1659/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001660static void *
paulfd79ac92004-10-13 05:06:08 +00001661route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001662{
1663 u_char *origin;
1664
1665 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1666
1667 if (strcmp (arg, "igp") == 0)
1668 *origin = 0;
1669 else if (strcmp (arg, "egp") == 0)
1670 *origin = 1;
1671 else
1672 *origin = 2;
1673
1674 return origin;
1675}
1676
1677/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001678static void
paul718e3742002-12-13 20:15:29 +00001679route_set_origin_free (void *rule)
1680{
1681 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1682}
1683
Timo Teräs2aa640b2014-05-20 08:57:26 +03001684/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001685struct route_map_rule_cmd route_set_origin_cmd =
1686{
1687 "origin",
1688 route_set_origin,
1689 route_set_origin_compile,
1690 route_set_origin_free,
1691};
David Lamparter6b0655a2014-06-04 06:53:35 +02001692
paul718e3742002-12-13 20:15:29 +00001693/* `set atomic-aggregate' */
1694
1695/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001696static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001697route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1698 route_map_object_t type, void *object)
1699{
1700 struct bgp_info *bgp_info;
1701
1702 if (type == RMAP_BGP)
1703 {
1704 bgp_info = object;
1705 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1706 }
1707
1708 return RMAP_OKAY;
1709}
1710
1711/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001712static void *
paulfd79ac92004-10-13 05:06:08 +00001713route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001714{
1715 return (void *)1;
1716}
1717
1718/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001719static void
paul718e3742002-12-13 20:15:29 +00001720route_set_atomic_aggregate_free (void *rule)
1721{
1722 return;
1723}
1724
1725/* Set atomic aggregate rule structure. */
1726struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1727{
1728 "atomic-aggregate",
1729 route_set_atomic_aggregate,
1730 route_set_atomic_aggregate_compile,
1731 route_set_atomic_aggregate_free,
1732};
David Lamparter6b0655a2014-06-04 06:53:35 +02001733
paul718e3742002-12-13 20:15:29 +00001734/* `set aggregator as AS A.B.C.D' */
1735struct aggregator
1736{
1737 as_t as;
1738 struct in_addr address;
1739};
1740
paul94f2b392005-06-28 12:44:16 +00001741static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001742route_set_aggregator_as (void *rule, struct prefix *prefix,
1743 route_map_object_t type, void *object)
1744{
1745 struct bgp_info *bgp_info;
1746 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001747 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001748
1749 if (type == RMAP_BGP)
1750 {
1751 bgp_info = object;
1752 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001753 ae = bgp_attr_extra_get (bgp_info->attr);
1754
1755 ae->aggregator_as = aggregator->as;
1756 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001757 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1758 }
1759
1760 return RMAP_OKAY;
1761}
1762
paul94f2b392005-06-28 12:44:16 +00001763static void *
paulfd79ac92004-10-13 05:06:08 +00001764route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001765{
1766 struct aggregator *aggregator;
1767 char as[10];
1768 char address[20];
1769
Stephen Hemminger393deb92008-08-18 14:13:29 -07001770 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001771 sscanf (arg, "%s %s", as, address);
1772
1773 aggregator->as = strtoul (as, NULL, 10);
1774 inet_aton (address, &aggregator->address);
1775
1776 return aggregator;
1777}
1778
paul94f2b392005-06-28 12:44:16 +00001779static void
paul718e3742002-12-13 20:15:29 +00001780route_set_aggregator_as_free (void *rule)
1781{
1782 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1783}
1784
1785struct route_map_rule_cmd route_set_aggregator_as_cmd =
1786{
1787 "aggregator as",
1788 route_set_aggregator_as,
1789 route_set_aggregator_as_compile,
1790 route_set_aggregator_as_free,
1791};
David Lamparter6b0655a2014-06-04 06:53:35 +02001792
paul718e3742002-12-13 20:15:29 +00001793#ifdef HAVE_IPV6
1794/* `match ipv6 address IP_ACCESS_LIST' */
1795
paul94f2b392005-06-28 12:44:16 +00001796static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001797route_match_ipv6_address (void *rule, struct prefix *prefix,
1798 route_map_object_t type, void *object)
1799{
1800 struct access_list *alist;
1801
1802 if (type == RMAP_BGP)
1803 {
1804 alist = access_list_lookup (AFI_IP6, (char *) rule);
1805 if (alist == NULL)
1806 return RMAP_NOMATCH;
1807
1808 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1809 RMAP_NOMATCH : RMAP_MATCH);
1810 }
1811 return RMAP_NOMATCH;
1812}
1813
paul94f2b392005-06-28 12:44:16 +00001814static void *
paulfd79ac92004-10-13 05:06:08 +00001815route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001816{
1817 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1818}
1819
paul94f2b392005-06-28 12:44:16 +00001820static void
paul718e3742002-12-13 20:15:29 +00001821route_match_ipv6_address_free (void *rule)
1822{
1823 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1824}
1825
1826/* Route map commands for ip address matching. */
1827struct route_map_rule_cmd route_match_ipv6_address_cmd =
1828{
1829 "ipv6 address",
1830 route_match_ipv6_address,
1831 route_match_ipv6_address_compile,
1832 route_match_ipv6_address_free
1833};
David Lamparter6b0655a2014-06-04 06:53:35 +02001834
paul718e3742002-12-13 20:15:29 +00001835/* `match ipv6 next-hop IP_ADDRESS' */
1836
paul94f2b392005-06-28 12:44:16 +00001837static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001838route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1839 route_map_object_t type, void *object)
1840{
1841 struct in6_addr *addr;
1842 struct bgp_info *bgp_info;
1843
1844 if (type == RMAP_BGP)
1845 {
1846 addr = rule;
1847 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001848
1849 if (!bgp_info->attr->extra)
1850 return RMAP_NOMATCH;
1851
1852 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001853 return RMAP_MATCH;
1854
Paul Jakmafb982c22007-05-04 20:15:47 +00001855 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1856 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001857 return RMAP_MATCH;
1858
1859 return RMAP_NOMATCH;
1860 }
1861
1862 return RMAP_NOMATCH;
1863}
1864
paul94f2b392005-06-28 12:44:16 +00001865static void *
paulfd79ac92004-10-13 05:06:08 +00001866route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001867{
1868 struct in6_addr *address;
1869 int ret;
1870
1871 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1872
1873 ret = inet_pton (AF_INET6, arg, address);
1874 if (!ret)
1875 {
1876 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1877 return NULL;
1878 }
1879
1880 return address;
1881}
1882
paul94f2b392005-06-28 12:44:16 +00001883static void
paul718e3742002-12-13 20:15:29 +00001884route_match_ipv6_next_hop_free (void *rule)
1885{
1886 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1887}
1888
1889struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1890{
1891 "ipv6 next-hop",
1892 route_match_ipv6_next_hop,
1893 route_match_ipv6_next_hop_compile,
1894 route_match_ipv6_next_hop_free
1895};
David Lamparter6b0655a2014-06-04 06:53:35 +02001896
paul718e3742002-12-13 20:15:29 +00001897/* `match ipv6 address prefix-list PREFIX_LIST' */
1898
paul94f2b392005-06-28 12:44:16 +00001899static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001900route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1901 route_map_object_t type, void *object)
1902{
1903 struct prefix_list *plist;
1904
1905 if (type == RMAP_BGP)
1906 {
1907 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1908 if (plist == NULL)
1909 return RMAP_NOMATCH;
1910
1911 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1912 RMAP_NOMATCH : RMAP_MATCH);
1913 }
1914 return RMAP_NOMATCH;
1915}
1916
paul94f2b392005-06-28 12:44:16 +00001917static void *
paulfd79ac92004-10-13 05:06:08 +00001918route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001919{
1920 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1921}
1922
paul94f2b392005-06-28 12:44:16 +00001923static void
paul718e3742002-12-13 20:15:29 +00001924route_match_ipv6_address_prefix_list_free (void *rule)
1925{
1926 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1927}
1928
1929struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1930{
1931 "ipv6 address prefix-list",
1932 route_match_ipv6_address_prefix_list,
1933 route_match_ipv6_address_prefix_list_compile,
1934 route_match_ipv6_address_prefix_list_free
1935};
David Lamparter6b0655a2014-06-04 06:53:35 +02001936
paul718e3742002-12-13 20:15:29 +00001937/* `set ipv6 nexthop global IP_ADDRESS' */
1938
1939/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001940static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001941route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1942 route_map_object_t type, void *object)
1943{
1944 struct in6_addr *address;
1945 struct bgp_info *bgp_info;
1946
1947 if (type == RMAP_BGP)
1948 {
1949 /* Fetch routemap's rule information. */
1950 address = rule;
1951 bgp_info = object;
1952
1953 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001954 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001955
1956 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001957 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1958 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001959 }
1960
1961 return RMAP_OKAY;
1962}
1963
1964/* Route map `ip next-hop' compile function. Given string is converted
1965 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001966static void *
paulfd79ac92004-10-13 05:06:08 +00001967route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001968{
1969 int ret;
1970 struct in6_addr *address;
1971
1972 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1973
1974 ret = inet_pton (AF_INET6, arg, address);
1975
1976 if (ret == 0)
1977 {
1978 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1979 return NULL;
1980 }
1981
1982 return address;
1983}
1984
1985/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001986static void
paul718e3742002-12-13 20:15:29 +00001987route_set_ipv6_nexthop_global_free (void *rule)
1988{
1989 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1990}
1991
1992/* Route map commands for ip nexthop set. */
1993struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1994{
1995 "ipv6 next-hop global",
1996 route_set_ipv6_nexthop_global,
1997 route_set_ipv6_nexthop_global_compile,
1998 route_set_ipv6_nexthop_global_free
1999};
David Lamparter6b0655a2014-06-04 06:53:35 +02002000
paul718e3742002-12-13 20:15:29 +00002001/* `set ipv6 nexthop local IP_ADDRESS' */
2002
2003/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002004static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002005route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2006 route_map_object_t type, void *object)
2007{
2008 struct in6_addr *address;
2009 struct bgp_info *bgp_info;
2010
2011 if (type == RMAP_BGP)
2012 {
2013 /* Fetch routemap's rule information. */
2014 address = rule;
2015 bgp_info = object;
2016
2017 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002018 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002019
2020 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002021 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2022 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002023 }
2024
2025 return RMAP_OKAY;
2026}
2027
2028/* Route map `ip nexthop' compile function. Given string is converted
2029 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002030static void *
paulfd79ac92004-10-13 05:06:08 +00002031route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002032{
2033 int ret;
2034 struct in6_addr *address;
2035
2036 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2037
2038 ret = inet_pton (AF_INET6, arg, address);
2039
2040 if (ret == 0)
2041 {
2042 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2043 return NULL;
2044 }
2045
2046 return address;
2047}
2048
2049/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002050static void
paul718e3742002-12-13 20:15:29 +00002051route_set_ipv6_nexthop_local_free (void *rule)
2052{
2053 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2054}
2055
2056/* Route map commands for ip nexthop set. */
2057struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2058{
2059 "ipv6 next-hop local",
2060 route_set_ipv6_nexthop_local,
2061 route_set_ipv6_nexthop_local_compile,
2062 route_set_ipv6_nexthop_local_free
2063};
2064#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02002065
paul718e3742002-12-13 20:15:29 +00002066/* `set vpnv4 nexthop A.B.C.D' */
2067
paul94f2b392005-06-28 12:44:16 +00002068static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002069route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2070 route_map_object_t type, void *object)
2071{
2072 struct in_addr *address;
2073 struct bgp_info *bgp_info;
2074
2075 if (type == RMAP_BGP)
2076 {
2077 /* Fetch routemap's rule information. */
2078 address = rule;
2079 bgp_info = object;
2080
2081 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002082 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002083 }
2084
2085 return RMAP_OKAY;
2086}
2087
paul94f2b392005-06-28 12:44:16 +00002088static void *
paulfd79ac92004-10-13 05:06:08 +00002089route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002090{
2091 int ret;
2092 struct in_addr *address;
2093
2094 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2095
2096 ret = inet_aton (arg, address);
2097
2098 if (ret == 0)
2099 {
2100 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2101 return NULL;
2102 }
2103
2104 return address;
2105}
2106
paul94f2b392005-06-28 12:44:16 +00002107static void
paul718e3742002-12-13 20:15:29 +00002108route_set_vpnv4_nexthop_free (void *rule)
2109{
2110 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2111}
2112
2113/* Route map commands for ip nexthop set. */
2114struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2115{
2116 "vpnv4 next-hop",
2117 route_set_vpnv4_nexthop,
2118 route_set_vpnv4_nexthop_compile,
2119 route_set_vpnv4_nexthop_free
2120};
David Lamparter6b0655a2014-06-04 06:53:35 +02002121
paul718e3742002-12-13 20:15:29 +00002122/* `set originator-id' */
2123
2124/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002125static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002126route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2127{
2128 struct in_addr *address;
2129 struct bgp_info *bgp_info;
2130
2131 if (type == RMAP_BGP)
2132 {
2133 address = rule;
2134 bgp_info = object;
2135
2136 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002137 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002138 }
2139
2140 return RMAP_OKAY;
2141}
2142
2143/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002144static void *
paulfd79ac92004-10-13 05:06:08 +00002145route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002146{
2147 int ret;
2148 struct in_addr *address;
2149
2150 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2151
2152 ret = inet_aton (arg, address);
2153
2154 if (ret == 0)
2155 {
2156 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2157 return NULL;
2158 }
2159
2160 return address;
2161}
2162
2163/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002164static void
paul718e3742002-12-13 20:15:29 +00002165route_set_originator_id_free (void *rule)
2166{
2167 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2168}
2169
Timo Teräs2aa640b2014-05-20 08:57:26 +03002170/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002171struct route_map_rule_cmd route_set_originator_id_cmd =
2172{
2173 "originator-id",
2174 route_set_originator_id,
2175 route_set_originator_id_compile,
2176 route_set_originator_id_free,
2177};
David Lamparter6b0655a2014-06-04 06:53:35 +02002178
paul718e3742002-12-13 20:15:29 +00002179/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002180static int
paul718e3742002-12-13 20:15:29 +00002181bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002182 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002183{
2184 int ret;
2185
2186 ret = route_map_add_match (index, command, arg);
2187 if (ret)
2188 {
2189 switch (ret)
2190 {
2191 case RMAP_RULE_MISSING:
2192 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2193 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002194 case RMAP_COMPILE_ERROR:
2195 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2196 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002197 }
2198 }
2199 return CMD_SUCCESS;
2200}
2201
2202/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002203static int
paul718e3742002-12-13 20:15:29 +00002204bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002205 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002206{
2207 int ret;
2208
2209 ret = route_map_delete_match (index, command, arg);
2210 if (ret)
2211 {
2212 switch (ret)
2213 {
2214 case RMAP_RULE_MISSING:
2215 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2216 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002217 case RMAP_COMPILE_ERROR:
2218 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2219 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002220 }
2221 }
2222 return CMD_SUCCESS;
2223}
2224
2225/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002226static int
paul718e3742002-12-13 20:15:29 +00002227bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002228 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002229{
2230 int ret;
2231
2232 ret = route_map_add_set (index, command, arg);
2233 if (ret)
2234 {
2235 switch (ret)
2236 {
2237 case RMAP_RULE_MISSING:
2238 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2239 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002240 case RMAP_COMPILE_ERROR:
2241 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2242 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002243 }
2244 }
2245 return CMD_SUCCESS;
2246}
2247
2248/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002249static int
paul718e3742002-12-13 20:15:29 +00002250bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002251 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002252{
2253 int ret;
2254
2255 ret = route_map_delete_set (index, command, arg);
2256 if (ret)
2257 {
2258 switch (ret)
2259 {
2260 case RMAP_RULE_MISSING:
2261 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2262 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002263 case RMAP_COMPILE_ERROR:
2264 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2265 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002266 }
2267 }
2268 return CMD_SUCCESS;
2269}
2270
2271/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002272static void
paulfd79ac92004-10-13 05:06:08 +00002273bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002274{
2275 int i;
2276 afi_t afi;
2277 safi_t safi;
2278 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002279 struct listnode *node, *nnode;
2280 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002281 struct bgp *bgp;
2282 struct peer *peer;
2283 struct peer_group *group;
2284 struct bgp_filter *filter;
2285 struct bgp_node *bn;
2286 struct bgp_static *bgp_static;
2287
2288 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002289 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002290 {
paul1eb8ef22005-04-07 07:30:20 +00002291 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002292 {
2293 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2294 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2295 {
2296 filter = &peer->filter[afi][safi];
2297
paulfee0f4c2004-09-13 05:12:46 +00002298 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002299 {
2300 if (filter->map[direct].name)
2301 filter->map[direct].map =
2302 route_map_lookup_by_name (filter->map[direct].name);
2303 else
2304 filter->map[direct].map = NULL;
2305 }
2306
2307 if (filter->usmap.name)
2308 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2309 else
2310 filter->usmap.map = NULL;
2311 }
2312 }
paul1eb8ef22005-04-07 07:30:20 +00002313 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002314 {
2315 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2316 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2317 {
2318 filter = &group->conf->filter[afi][safi];
2319
paulfee0f4c2004-09-13 05:12:46 +00002320 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002321 {
2322 if (filter->map[direct].name)
2323 filter->map[direct].map =
2324 route_map_lookup_by_name (filter->map[direct].name);
2325 else
2326 filter->map[direct].map = NULL;
2327 }
2328
2329 if (filter->usmap.name)
2330 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2331 else
2332 filter->usmap.map = NULL;
2333 }
2334 }
2335 }
2336
2337 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002338 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002339 {
paul1eb8ef22005-04-07 07:30:20 +00002340 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002341 {
2342 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2343 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2344 {
2345 if (peer->default_rmap[afi][safi].name)
2346 peer->default_rmap[afi][safi].map =
2347 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2348 else
2349 peer->default_rmap[afi][safi].map = NULL;
2350 }
2351 }
2352 }
2353
2354 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002355 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002356 {
2357 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2358 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2359 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2360 bn = bgp_route_next (bn))
2361 if ((bgp_static = bn->info) != NULL)
2362 {
2363 if (bgp_static->rmap.name)
2364 bgp_static->rmap.map =
2365 route_map_lookup_by_name (bgp_static->rmap.name);
2366 else
2367 bgp_static->rmap.map = NULL;
2368 }
2369 }
2370
2371 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002372 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002373 {
2374 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2375 {
2376 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2377 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2378 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2379#ifdef HAVE_IPV6
2380 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2381 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2382 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2383#endif /* HAVE_IPV6 */
2384 }
2385 }
2386}
David Lamparter6b0655a2014-06-04 06:53:35 +02002387
paulfee0f4c2004-09-13 05:12:46 +00002388DEFUN (match_peer,
2389 match_peer_cmd,
2390 "match peer (A.B.C.D|X:X::X:X)",
2391 MATCH_STR
2392 "Match peer address\n"
2393 "IPv6 address of peer\n"
2394 "IP address of peer\n")
2395{
2396 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2397}
2398
2399DEFUN (match_peer_local,
2400 match_peer_local_cmd,
2401 "match peer local",
2402 MATCH_STR
2403 "Match peer address\n"
2404 "Static or Redistributed routes\n")
2405{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002406 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002407}
2408
2409DEFUN (no_match_peer,
2410 no_match_peer_cmd,
2411 "no match peer",
2412 NO_STR
2413 MATCH_STR
2414 "Match peer address\n")
2415{
2416 if (argc == 0)
2417 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2418
2419 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2420}
2421
2422ALIAS (no_match_peer,
2423 no_match_peer_val_cmd,
2424 "no match peer (A.B.C.D|X:X::X:X)",
2425 NO_STR
2426 MATCH_STR
2427 "Match peer address\n"
2428 "IPv6 address of peer\n"
2429 "IP address of peer\n")
2430
2431ALIAS (no_match_peer,
2432 no_match_peer_local_cmd,
2433 "no match peer local",
2434 NO_STR
2435 MATCH_STR
2436 "Match peer address\n"
2437 "Static or Redistributed routes\n")
2438
paul718e3742002-12-13 20:15:29 +00002439DEFUN (match_ip_address,
2440 match_ip_address_cmd,
2441 "match ip address (<1-199>|<1300-2699>|WORD)",
2442 MATCH_STR
2443 IP_STR
2444 "Match address of route\n"
2445 "IP access-list number\n"
2446 "IP access-list number (expanded range)\n"
2447 "IP Access-list name\n")
2448{
2449 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2450}
2451
2452DEFUN (no_match_ip_address,
2453 no_match_ip_address_cmd,
2454 "no match ip address",
2455 NO_STR
2456 MATCH_STR
2457 IP_STR
2458 "Match address of route\n")
2459{
2460 if (argc == 0)
2461 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2462
2463 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2464}
2465
2466ALIAS (no_match_ip_address,
2467 no_match_ip_address_val_cmd,
2468 "no match ip address (<1-199>|<1300-2699>|WORD)",
2469 NO_STR
2470 MATCH_STR
2471 IP_STR
2472 "Match address of route\n"
2473 "IP access-list number\n"
2474 "IP access-list number (expanded range)\n"
2475 "IP Access-list name\n")
2476
2477DEFUN (match_ip_next_hop,
2478 match_ip_next_hop_cmd,
2479 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2480 MATCH_STR
2481 IP_STR
2482 "Match next-hop address of route\n"
2483 "IP access-list number\n"
2484 "IP access-list number (expanded range)\n"
2485 "IP Access-list name\n")
2486{
2487 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2488}
2489
2490DEFUN (no_match_ip_next_hop,
2491 no_match_ip_next_hop_cmd,
2492 "no match ip next-hop",
2493 NO_STR
2494 MATCH_STR
2495 IP_STR
2496 "Match next-hop address of route\n")
2497{
2498 if (argc == 0)
2499 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2500
2501 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2502}
2503
2504ALIAS (no_match_ip_next_hop,
2505 no_match_ip_next_hop_val_cmd,
2506 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2507 NO_STR
2508 MATCH_STR
2509 IP_STR
2510 "Match next-hop address of route\n"
2511 "IP access-list number\n"
2512 "IP access-list number (expanded range)\n"
2513 "IP Access-list name\n")
2514
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002515/* match probability { */
2516
2517DEFUN (match_probability,
2518 match_probability_cmd,
2519 "match probability <0-100>",
2520 MATCH_STR
2521 "Match portion of routes defined by percentage value\n"
2522 "Percentage of routes\n")
2523{
2524 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2525}
2526
2527DEFUN (no_match_probability,
2528 no_match_probability_cmd,
2529 "no match probability",
2530 NO_STR
2531 MATCH_STR
2532 "Match portion of routes defined by percentage value\n")
2533{
2534 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2535}
2536
2537ALIAS (no_match_probability,
2538 no_match_probability_val_cmd,
2539 "no match probability <1-99>",
2540 NO_STR
2541 MATCH_STR
2542 "Match portion of routes defined by percentage value\n"
2543 "Percentage of routes\n")
2544
2545/* } */
2546
hassoc1643bb2005-02-02 16:43:17 +00002547DEFUN (match_ip_route_source,
2548 match_ip_route_source_cmd,
2549 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2550 MATCH_STR
2551 IP_STR
2552 "Match advertising source address of route\n"
2553 "IP access-list number\n"
2554 "IP access-list number (expanded range)\n"
2555 "IP standard access-list name\n")
2556{
2557 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2558}
2559
2560DEFUN (no_match_ip_route_source,
2561 no_match_ip_route_source_cmd,
2562 "no match ip route-source",
2563 NO_STR
2564 MATCH_STR
2565 IP_STR
2566 "Match advertising source address of route\n")
2567{
2568 if (argc == 0)
2569 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2570
2571 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2572}
2573
2574ALIAS (no_match_ip_route_source,
2575 no_match_ip_route_source_val_cmd,
2576 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2577 NO_STR
2578 MATCH_STR
2579 IP_STR
2580 "Match advertising source address of route\n"
2581 "IP access-list number\n"
2582 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002583 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002584
paul718e3742002-12-13 20:15:29 +00002585DEFUN (match_ip_address_prefix_list,
2586 match_ip_address_prefix_list_cmd,
2587 "match ip address prefix-list WORD",
2588 MATCH_STR
2589 IP_STR
2590 "Match address of route\n"
2591 "Match entries of prefix-lists\n"
2592 "IP prefix-list name\n")
2593{
2594 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2595}
2596
2597DEFUN (no_match_ip_address_prefix_list,
2598 no_match_ip_address_prefix_list_cmd,
2599 "no match ip address prefix-list",
2600 NO_STR
2601 MATCH_STR
2602 IP_STR
2603 "Match address of route\n"
2604 "Match entries of prefix-lists\n")
2605{
2606 if (argc == 0)
2607 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2608
2609 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2610}
2611
2612ALIAS (no_match_ip_address_prefix_list,
2613 no_match_ip_address_prefix_list_val_cmd,
2614 "no match ip address prefix-list WORD",
2615 NO_STR
2616 MATCH_STR
2617 IP_STR
2618 "Match address of route\n"
2619 "Match entries of prefix-lists\n"
2620 "IP prefix-list name\n")
2621
2622DEFUN (match_ip_next_hop_prefix_list,
2623 match_ip_next_hop_prefix_list_cmd,
2624 "match ip next-hop prefix-list WORD",
2625 MATCH_STR
2626 IP_STR
2627 "Match next-hop address of route\n"
2628 "Match entries of prefix-lists\n"
2629 "IP prefix-list name\n")
2630{
2631 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2632}
2633
2634DEFUN (no_match_ip_next_hop_prefix_list,
2635 no_match_ip_next_hop_prefix_list_cmd,
2636 "no match ip next-hop prefix-list",
2637 NO_STR
2638 MATCH_STR
2639 IP_STR
2640 "Match next-hop address of route\n"
2641 "Match entries of prefix-lists\n")
2642{
2643 if (argc == 0)
2644 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2645
2646 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2647}
2648
2649ALIAS (no_match_ip_next_hop_prefix_list,
2650 no_match_ip_next_hop_prefix_list_val_cmd,
2651 "no match ip next-hop prefix-list WORD",
2652 NO_STR
2653 MATCH_STR
2654 IP_STR
2655 "Match next-hop address of route\n"
2656 "Match entries of prefix-lists\n"
2657 "IP prefix-list name\n")
2658
hassoc1643bb2005-02-02 16:43:17 +00002659DEFUN (match_ip_route_source_prefix_list,
2660 match_ip_route_source_prefix_list_cmd,
2661 "match ip route-source prefix-list WORD",
2662 MATCH_STR
2663 IP_STR
2664 "Match advertising source address of route\n"
2665 "Match entries of prefix-lists\n"
2666 "IP prefix-list name\n")
2667{
2668 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2669}
2670
2671DEFUN (no_match_ip_route_source_prefix_list,
2672 no_match_ip_route_source_prefix_list_cmd,
2673 "no match ip route-source prefix-list",
2674 NO_STR
2675 MATCH_STR
2676 IP_STR
2677 "Match advertising source address of route\n"
2678 "Match entries of prefix-lists\n")
2679{
2680 if (argc == 0)
2681 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2682
2683 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2684}
2685
2686ALIAS (no_match_ip_route_source_prefix_list,
2687 no_match_ip_route_source_prefix_list_val_cmd,
2688 "no match ip route-source prefix-list WORD",
2689 NO_STR
2690 MATCH_STR
2691 IP_STR
2692 "Match advertising source address of route\n"
2693 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002694 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002695
paul718e3742002-12-13 20:15:29 +00002696DEFUN (match_metric,
2697 match_metric_cmd,
2698 "match metric <0-4294967295>",
2699 MATCH_STR
2700 "Match metric of route\n"
2701 "Metric value\n")
2702{
2703 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2704}
2705
2706DEFUN (no_match_metric,
2707 no_match_metric_cmd,
2708 "no match metric",
2709 NO_STR
2710 MATCH_STR
2711 "Match metric of route\n")
2712{
2713 if (argc == 0)
2714 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2715
2716 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2717}
2718
2719ALIAS (no_match_metric,
2720 no_match_metric_val_cmd,
2721 "no match metric <0-4294967295>",
2722 NO_STR
2723 MATCH_STR
2724 "Match metric of route\n"
2725 "Metric value\n")
2726
2727DEFUN (match_community,
2728 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002729 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002730 MATCH_STR
2731 "Match BGP community list\n"
2732 "Community-list number (standard)\n"
2733 "Community-list number (expanded)\n"
2734 "Community-list name\n")
2735{
2736 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2737}
2738
2739DEFUN (match_community_exact,
2740 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002741 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002742 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 "Do exact matching of communities\n")
2748{
2749 int ret;
2750 char *argstr;
2751
2752 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2753 strlen (argv[0]) + strlen ("exact-match") + 2);
2754
2755 sprintf (argstr, "%s exact-match", argv[0]);
2756
2757 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2758
2759 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2760
2761 return ret;
2762}
2763
2764DEFUN (no_match_community,
2765 no_match_community_cmd,
2766 "no match community",
2767 NO_STR
2768 MATCH_STR
2769 "Match BGP community list\n")
2770{
2771 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2772}
2773
2774ALIAS (no_match_community,
2775 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002776 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002777 NO_STR
2778 MATCH_STR
2779 "Match BGP community list\n"
2780 "Community-list number (standard)\n"
2781 "Community-list number (expanded)\n"
2782 "Community-list name\n")
2783
2784ALIAS (no_match_community,
2785 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002786 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002787 NO_STR
2788 MATCH_STR
2789 "Match BGP community list\n"
2790 "Community-list number (standard)\n"
2791 "Community-list number (expanded)\n"
2792 "Community-list name\n"
2793 "Do exact matching of communities\n")
2794
paul73ffb252003-04-19 15:49:49 +00002795DEFUN (match_ecommunity,
2796 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002797 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002798 MATCH_STR
2799 "Match BGP/VPN extended community list\n"
2800 "Extended community-list number (standard)\n"
2801 "Extended community-list number (expanded)\n"
2802 "Extended community-list name\n")
2803{
2804 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2805}
2806
2807DEFUN (no_match_ecommunity,
2808 no_match_ecommunity_cmd,
2809 "no match extcommunity",
2810 NO_STR
2811 MATCH_STR
2812 "Match BGP/VPN extended community list\n")
2813{
2814 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2815}
2816
2817ALIAS (no_match_ecommunity,
2818 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002819 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002820 NO_STR
2821 MATCH_STR
2822 "Match BGP/VPN extended community list\n"
2823 "Extended community-list number (standard)\n"
2824 "Extended community-list number (expanded)\n"
2825 "Extended community-list name\n")
2826
paul718e3742002-12-13 20:15:29 +00002827DEFUN (match_aspath,
2828 match_aspath_cmd,
2829 "match as-path WORD",
2830 MATCH_STR
2831 "Match BGP AS path list\n"
2832 "AS path access-list name\n")
2833{
2834 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2835}
2836
2837DEFUN (no_match_aspath,
2838 no_match_aspath_cmd,
2839 "no match as-path",
2840 NO_STR
2841 MATCH_STR
2842 "Match BGP AS path list\n")
2843{
2844 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2845}
2846
2847ALIAS (no_match_aspath,
2848 no_match_aspath_val_cmd,
2849 "no match as-path WORD",
2850 NO_STR
2851 MATCH_STR
2852 "Match BGP AS path list\n"
2853 "AS path access-list name\n")
2854
2855DEFUN (match_origin,
2856 match_origin_cmd,
2857 "match origin (egp|igp|incomplete)",
2858 MATCH_STR
2859 "BGP origin code\n"
2860 "remote EGP\n"
2861 "local IGP\n"
2862 "unknown heritage\n")
2863{
2864 if (strncmp (argv[0], "igp", 2) == 0)
2865 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2866 if (strncmp (argv[0], "egp", 1) == 0)
2867 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2868 if (strncmp (argv[0], "incomplete", 2) == 0)
2869 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2870
2871 return CMD_WARNING;
2872}
2873
2874DEFUN (no_match_origin,
2875 no_match_origin_cmd,
2876 "no match origin",
2877 NO_STR
2878 MATCH_STR
2879 "BGP origin code\n")
2880{
2881 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2882}
2883
2884ALIAS (no_match_origin,
2885 no_match_origin_val_cmd,
2886 "no match origin (egp|igp|incomplete)",
2887 NO_STR
2888 MATCH_STR
2889 "BGP origin code\n"
2890 "remote EGP\n"
2891 "local IGP\n"
2892 "unknown heritage\n")
2893
2894DEFUN (set_ip_nexthop,
2895 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002896 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002897 SET_STR
2898 IP_STR
2899 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002900 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002901{
2902 union sockunion su;
2903 int ret;
2904
2905 ret = str2sockunion (argv[0], &su);
2906 if (ret < 0)
2907 {
2908 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2909 return CMD_WARNING;
2910 }
2911
2912 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2913}
2914
paulaf5cd0a2003-11-02 07:24:40 +00002915DEFUN (set_ip_nexthop_peer,
2916 set_ip_nexthop_peer_cmd,
2917 "set ip next-hop peer-address",
2918 SET_STR
2919 IP_STR
2920 "Next hop address\n"
2921 "Use peer address (for BGP only)\n")
2922{
2923 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2924}
2925
paul94f2b392005-06-28 12:44:16 +00002926DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002927 no_set_ip_nexthop_peer_cmd,
2928 "no set ip next-hop peer-address",
2929 NO_STR
2930 SET_STR
2931 IP_STR
2932 "Next hop address\n"
2933 "Use peer address (for BGP only)\n")
2934{
2935 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2936}
2937
2938
paul718e3742002-12-13 20:15:29 +00002939DEFUN (no_set_ip_nexthop,
2940 no_set_ip_nexthop_cmd,
2941 "no set ip next-hop",
2942 NO_STR
2943 SET_STR
paul718e3742002-12-13 20:15:29 +00002944 "Next hop address\n")
2945{
paulaf5cd0a2003-11-02 07:24:40 +00002946 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002947 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2948
2949 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2950}
2951
2952ALIAS (no_set_ip_nexthop,
2953 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002954 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002955 NO_STR
2956 SET_STR
2957 IP_STR
2958 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002959 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002960
2961DEFUN (set_metric,
2962 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002963 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002964 SET_STR
2965 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002966 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002967{
2968 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2969}
2970
paul73ffb252003-04-19 15:49:49 +00002971ALIAS (set_metric,
2972 set_metric_addsub_cmd,
2973 "set metric <+/-metric>",
2974 SET_STR
2975 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002976 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002977
paul718e3742002-12-13 20:15:29 +00002978DEFUN (no_set_metric,
2979 no_set_metric_cmd,
2980 "no set metric",
2981 NO_STR
2982 SET_STR
2983 "Metric value for destination routing protocol\n")
2984{
2985 if (argc == 0)
2986 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2987
2988 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2989}
2990
2991ALIAS (no_set_metric,
2992 no_set_metric_val_cmd,
2993 "no set metric <0-4294967295>",
2994 NO_STR
2995 SET_STR
2996 "Metric value for destination routing protocol\n"
2997 "Metric value\n")
2998
2999DEFUN (set_local_pref,
3000 set_local_pref_cmd,
3001 "set local-preference <0-4294967295>",
3002 SET_STR
3003 "BGP local preference path attribute\n"
3004 "Preference value\n")
3005{
3006 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3007}
3008
3009DEFUN (no_set_local_pref,
3010 no_set_local_pref_cmd,
3011 "no set local-preference",
3012 NO_STR
3013 SET_STR
3014 "BGP local preference path attribute\n")
3015{
3016 if (argc == 0)
3017 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3018
3019 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3020}
3021
3022ALIAS (no_set_local_pref,
3023 no_set_local_pref_val_cmd,
3024 "no set local-preference <0-4294967295>",
3025 NO_STR
3026 SET_STR
3027 "BGP local preference path attribute\n"
3028 "Preference value\n")
3029
3030DEFUN (set_weight,
3031 set_weight_cmd,
3032 "set weight <0-4294967295>",
3033 SET_STR
3034 "BGP weight for routing table\n"
3035 "Weight value\n")
3036{
3037 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3038}
3039
3040DEFUN (no_set_weight,
3041 no_set_weight_cmd,
3042 "no set weight",
3043 NO_STR
3044 SET_STR
3045 "BGP weight for routing table\n")
3046{
3047 if (argc == 0)
3048 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3049
3050 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3051}
3052
3053ALIAS (no_set_weight,
3054 no_set_weight_val_cmd,
3055 "no set weight <0-4294967295>",
3056 NO_STR
3057 SET_STR
3058 "BGP weight for routing table\n"
3059 "Weight value\n")
3060
3061DEFUN (set_aspath_prepend,
3062 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003063 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003064 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003065 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003066 "Prepend to the as-path\n"
3067 "AS number\n")
3068{
3069 int ret;
3070 char *str;
3071
3072 str = argv_concat (argv, argc, 0);
3073 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3074 XFREE (MTYPE_TMP, str);
3075
3076 return ret;
3077}
3078
3079DEFUN (no_set_aspath_prepend,
3080 no_set_aspath_prepend_cmd,
3081 "no set as-path prepend",
3082 NO_STR
3083 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003084 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003085 "Prepend to the as-path\n")
3086{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003087 int ret;
3088 char *str;
3089
3090 if (argc == 0)
3091 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3092
3093 str = argv_concat (argv, argc, 0);
3094 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3095 XFREE (MTYPE_TMP, str);
3096 return ret;
paul718e3742002-12-13 20:15:29 +00003097}
3098
3099ALIAS (no_set_aspath_prepend,
3100 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003101 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003102 NO_STR
3103 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003104 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003105 "Prepend to the as-path\n"
3106 "AS number\n")
3107
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003108DEFUN (set_aspath_exclude,
3109 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003110 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003111 SET_STR
3112 "Transform BGP AS-path attribute\n"
3113 "Exclude from the as-path\n"
3114 "AS number\n")
3115{
3116 int ret;
3117 char *str;
3118
3119 str = argv_concat (argv, argc, 0);
3120 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3121 XFREE (MTYPE_TMP, str);
3122 return ret;
3123}
3124
3125DEFUN (no_set_aspath_exclude,
3126 no_set_aspath_exclude_cmd,
3127 "no set as-path exclude",
3128 NO_STR
3129 SET_STR
3130 "Transform BGP AS_PATH attribute\n"
3131 "Exclude from the as-path\n")
3132{
3133 int ret;
3134 char *str;
3135
3136 if (argc == 0)
3137 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3138
3139 str = argv_concat (argv, argc, 0);
3140 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3141 XFREE (MTYPE_TMP, str);
3142 return ret;
3143}
3144
3145ALIAS (no_set_aspath_exclude,
3146 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003147 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003148 NO_STR
3149 SET_STR
3150 "Transform BGP AS_PATH attribute\n"
3151 "Exclude from the as-path\n"
3152 "AS number\n")
3153
paul718e3742002-12-13 20:15:29 +00003154DEFUN (set_community,
3155 set_community_cmd,
3156 "set community .AA:NN",
3157 SET_STR
3158 "BGP community attribute\n"
3159 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3160{
3161 int i;
3162 int first = 0;
3163 int additive = 0;
3164 struct buffer *b;
3165 struct community *com = NULL;
3166 char *str;
3167 char *argstr;
3168 int ret;
3169
3170 b = buffer_new (1024);
3171
3172 for (i = 0; i < argc; i++)
3173 {
3174 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3175 {
3176 additive = 1;
3177 continue;
3178 }
3179
3180 if (first)
3181 buffer_putc (b, ' ');
3182 else
3183 first = 1;
3184
3185 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3186 {
3187 buffer_putstr (b, "internet");
3188 continue;
3189 }
3190 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3191 {
3192 buffer_putstr (b, "local-AS");
3193 continue;
3194 }
3195 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3196 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3197 {
3198 buffer_putstr (b, "no-advertise");
3199 continue;
3200 }
3201 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3202 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3203 {
3204 buffer_putstr (b, "no-export");
3205 continue;
3206 }
3207 buffer_putstr (b, argv[i]);
3208 }
3209 buffer_putc (b, '\0');
3210
3211 /* Fetch result string then compile it to communities attribute. */
3212 str = buffer_getstr (b);
3213 buffer_free (b);
3214
3215 if (str)
3216 {
3217 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003218 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003219 }
3220
3221 /* Can't compile user input into communities attribute. */
3222 if (! com)
3223 {
3224 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3225 return CMD_WARNING;
3226 }
3227
3228 /* Set communites attribute string. */
3229 str = community_str (com);
3230
3231 if (additive)
3232 {
3233 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3234 strcpy (argstr, str);
3235 strcpy (argstr + strlen (str), " additive");
3236 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3237 XFREE (MTYPE_TMP, argstr);
3238 }
3239 else
3240 ret = bgp_route_set_add (vty, vty->index, "community", str);
3241
3242 community_free (com);
3243
3244 return ret;
3245}
3246
3247DEFUN (set_community_none,
3248 set_community_none_cmd,
3249 "set community none",
3250 SET_STR
3251 "BGP community attribute\n"
3252 "No community attribute\n")
3253{
3254 return bgp_route_set_add (vty, vty->index, "community", "none");
3255}
3256
3257DEFUN (no_set_community,
3258 no_set_community_cmd,
3259 "no set community",
3260 NO_STR
3261 SET_STR
3262 "BGP community attribute\n")
3263{
3264 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3265}
3266
3267ALIAS (no_set_community,
3268 no_set_community_val_cmd,
3269 "no set community .AA:NN",
3270 NO_STR
3271 SET_STR
3272 "BGP community attribute\n"
3273 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3274
3275ALIAS (no_set_community,
3276 no_set_community_none_cmd,
3277 "no set community none",
3278 NO_STR
3279 SET_STR
3280 "BGP community attribute\n"
3281 "No community attribute\n")
3282
3283DEFUN (set_community_delete,
3284 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003285 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003286 SET_STR
3287 "set BGP community list (for deletion)\n"
3288 "Community-list number (standard)\n"
3289 "Communitly-list number (expanded)\n"
3290 "Community-list name\n"
3291 "Delete matching communities\n")
3292{
3293 char *str;
3294
3295 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3296 strcpy (str, argv[0]);
3297 strcpy (str + strlen (argv[0]), " delete");
3298
3299 bgp_route_set_add (vty, vty->index, "comm-list", str);
3300
3301 XFREE (MTYPE_TMP, str);
3302 return CMD_SUCCESS;
3303}
3304
3305DEFUN (no_set_community_delete,
3306 no_set_community_delete_cmd,
3307 "no set comm-list",
3308 NO_STR
3309 SET_STR
3310 "set BGP community list (for deletion)\n")
3311{
3312 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3313}
3314
3315ALIAS (no_set_community_delete,
3316 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003317 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003318 NO_STR
3319 SET_STR
3320 "set BGP community list (for deletion)\n"
3321 "Community-list number (standard)\n"
3322 "Communitly-list number (expanded)\n"
3323 "Community-list name\n"
3324 "Delete matching communities\n")
3325
3326DEFUN (set_ecommunity_rt,
3327 set_ecommunity_rt_cmd,
3328 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3329 SET_STR
3330 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003331 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003332 "VPN extended community\n")
3333{
3334 int ret;
3335 char *str;
3336
3337 str = argv_concat (argv, argc, 0);
3338 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3339 XFREE (MTYPE_TMP, str);
3340
3341 return ret;
3342}
3343
3344DEFUN (no_set_ecommunity_rt,
3345 no_set_ecommunity_rt_cmd,
3346 "no set extcommunity rt",
3347 NO_STR
3348 SET_STR
3349 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003350 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003351{
3352 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3353}
3354
3355ALIAS (no_set_ecommunity_rt,
3356 no_set_ecommunity_rt_val_cmd,
3357 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3358 NO_STR
3359 SET_STR
3360 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003361 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003362 "VPN extended community\n")
3363
3364DEFUN (set_ecommunity_soo,
3365 set_ecommunity_soo_cmd,
3366 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3367 SET_STR
3368 "BGP extended community attribute\n"
3369 "Site-of-Origin extended community\n"
3370 "VPN extended community\n")
3371{
3372 int ret;
3373 char *str;
3374
3375 str = argv_concat (argv, argc, 0);
3376 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3377 XFREE (MTYPE_TMP, str);
3378 return ret;
3379}
3380
3381DEFUN (no_set_ecommunity_soo,
3382 no_set_ecommunity_soo_cmd,
3383 "no set extcommunity soo",
3384 NO_STR
3385 SET_STR
3386 "BGP extended community attribute\n"
3387 "Site-of-Origin extended community\n")
3388{
3389 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3390}
3391
3392ALIAS (no_set_ecommunity_soo,
3393 no_set_ecommunity_soo_val_cmd,
3394 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3395 NO_STR
3396 SET_STR
3397 "BGP extended community attribute\n"
3398 "Site-of-Origin extended community\n"
3399 "VPN extended community\n")
3400
3401DEFUN (set_origin,
3402 set_origin_cmd,
3403 "set origin (egp|igp|incomplete)",
3404 SET_STR
3405 "BGP origin code\n"
3406 "remote EGP\n"
3407 "local IGP\n"
3408 "unknown heritage\n")
3409{
3410 if (strncmp (argv[0], "igp", 2) == 0)
3411 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3412 if (strncmp (argv[0], "egp", 1) == 0)
3413 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3414 if (strncmp (argv[0], "incomplete", 2) == 0)
3415 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3416
3417 return CMD_WARNING;
3418}
3419
3420DEFUN (no_set_origin,
3421 no_set_origin_cmd,
3422 "no set origin",
3423 NO_STR
3424 SET_STR
3425 "BGP origin code\n")
3426{
3427 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3428}
3429
3430ALIAS (no_set_origin,
3431 no_set_origin_val_cmd,
3432 "no set origin (egp|igp|incomplete)",
3433 NO_STR
3434 SET_STR
3435 "BGP origin code\n"
3436 "remote EGP\n"
3437 "local IGP\n"
3438 "unknown heritage\n")
3439
3440DEFUN (set_atomic_aggregate,
3441 set_atomic_aggregate_cmd,
3442 "set atomic-aggregate",
3443 SET_STR
3444 "BGP atomic aggregate attribute\n" )
3445{
3446 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3447}
3448
3449DEFUN (no_set_atomic_aggregate,
3450 no_set_atomic_aggregate_cmd,
3451 "no set atomic-aggregate",
3452 NO_STR
3453 SET_STR
3454 "BGP atomic aggregate attribute\n" )
3455{
3456 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3457}
3458
3459DEFUN (set_aggregator_as,
3460 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003461 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003462 SET_STR
3463 "BGP aggregator attribute\n"
3464 "AS number of aggregator\n"
3465 "AS number\n"
3466 "IP address of aggregator\n")
3467{
3468 int ret;
3469 as_t as;
3470 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003471 char *argstr;
3472
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003473 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003474
paul718e3742002-12-13 20:15:29 +00003475 ret = inet_aton (argv[1], &address);
3476 if (ret == 0)
3477 {
3478 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3479 return CMD_WARNING;
3480 }
3481
3482 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3483 strlen (argv[0]) + strlen (argv[1]) + 2);
3484
3485 sprintf (argstr, "%s %s", argv[0], argv[1]);
3486
3487 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3488
3489 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3490
3491 return ret;
3492}
3493
3494DEFUN (no_set_aggregator_as,
3495 no_set_aggregator_as_cmd,
3496 "no set aggregator as",
3497 NO_STR
3498 SET_STR
3499 "BGP aggregator attribute\n"
3500 "AS number of aggregator\n")
3501{
3502 int ret;
3503 as_t as;
3504 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003505 char *argstr;
3506
3507 if (argv == 0)
3508 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3509
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003510 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003511
3512 ret = inet_aton (argv[1], &address);
3513 if (ret == 0)
3514 {
3515 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3516 return CMD_WARNING;
3517 }
3518
3519 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3520 strlen (argv[0]) + strlen (argv[1]) + 2);
3521
3522 sprintf (argstr, "%s %s", argv[0], argv[1]);
3523
3524 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3525
3526 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3527
3528 return ret;
3529}
3530
3531ALIAS (no_set_aggregator_as,
3532 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003533 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003534 NO_STR
3535 SET_STR
3536 "BGP aggregator attribute\n"
3537 "AS number of aggregator\n"
3538 "AS number\n"
3539 "IP address of aggregator\n")
3540
David Lamparter6b0655a2014-06-04 06:53:35 +02003541
paul718e3742002-12-13 20:15:29 +00003542#ifdef HAVE_IPV6
3543DEFUN (match_ipv6_address,
3544 match_ipv6_address_cmd,
3545 "match ipv6 address WORD",
3546 MATCH_STR
3547 IPV6_STR
3548 "Match IPv6 address of route\n"
3549 "IPv6 access-list name\n")
3550{
3551 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3552}
3553
3554DEFUN (no_match_ipv6_address,
3555 no_match_ipv6_address_cmd,
3556 "no match ipv6 address WORD",
3557 NO_STR
3558 MATCH_STR
3559 IPV6_STR
3560 "Match IPv6 address of route\n"
3561 "IPv6 access-list name\n")
3562{
3563 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3564}
3565
3566DEFUN (match_ipv6_next_hop,
3567 match_ipv6_next_hop_cmd,
3568 "match ipv6 next-hop X:X::X:X",
3569 MATCH_STR
3570 IPV6_STR
3571 "Match IPv6 next-hop address of route\n"
3572 "IPv6 address of next hop\n")
3573{
3574 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3575}
3576
3577DEFUN (no_match_ipv6_next_hop,
3578 no_match_ipv6_next_hop_cmd,
3579 "no match ipv6 next-hop X:X::X:X",
3580 NO_STR
3581 MATCH_STR
3582 IPV6_STR
3583 "Match IPv6 next-hop address of route\n"
3584 "IPv6 address of next hop\n")
3585{
3586 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3587}
3588
3589DEFUN (match_ipv6_address_prefix_list,
3590 match_ipv6_address_prefix_list_cmd,
3591 "match ipv6 address prefix-list WORD",
3592 MATCH_STR
3593 IPV6_STR
3594 "Match address of route\n"
3595 "Match entries of prefix-lists\n"
3596 "IP prefix-list name\n")
3597{
3598 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3599}
3600
3601DEFUN (no_match_ipv6_address_prefix_list,
3602 no_match_ipv6_address_prefix_list_cmd,
3603 "no match ipv6 address prefix-list WORD",
3604 NO_STR
3605 MATCH_STR
3606 IPV6_STR
3607 "Match address of route\n"
3608 "Match entries of prefix-lists\n"
3609 "IP prefix-list name\n")
3610{
3611 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3612}
3613
3614DEFUN (set_ipv6_nexthop_global,
3615 set_ipv6_nexthop_global_cmd,
3616 "set ipv6 next-hop global X:X::X:X",
3617 SET_STR
3618 IPV6_STR
3619 "IPv6 next-hop address\n"
3620 "IPv6 global address\n"
3621 "IPv6 address of next hop\n")
3622{
3623 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3624}
3625
3626DEFUN (no_set_ipv6_nexthop_global,
3627 no_set_ipv6_nexthop_global_cmd,
3628 "no set ipv6 next-hop global",
3629 NO_STR
3630 SET_STR
3631 IPV6_STR
3632 "IPv6 next-hop address\n"
3633 "IPv6 global address\n")
3634{
3635 if (argc == 0)
3636 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3637
3638 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3639}
3640
3641ALIAS (no_set_ipv6_nexthop_global,
3642 no_set_ipv6_nexthop_global_val_cmd,
3643 "no set ipv6 next-hop global X:X::X:X",
3644 NO_STR
3645 SET_STR
3646 IPV6_STR
3647 "IPv6 next-hop address\n"
3648 "IPv6 global address\n"
3649 "IPv6 address of next hop\n")
3650
3651DEFUN (set_ipv6_nexthop_local,
3652 set_ipv6_nexthop_local_cmd,
3653 "set ipv6 next-hop local X:X::X:X",
3654 SET_STR
3655 IPV6_STR
3656 "IPv6 next-hop address\n"
3657 "IPv6 local address\n"
3658 "IPv6 address of next hop\n")
3659{
3660 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3661}
3662
3663DEFUN (no_set_ipv6_nexthop_local,
3664 no_set_ipv6_nexthop_local_cmd,
3665 "no set ipv6 next-hop local",
3666 NO_STR
3667 SET_STR
3668 IPV6_STR
3669 "IPv6 next-hop address\n"
3670 "IPv6 local address\n")
3671{
3672 if (argc == 0)
3673 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3674
3675 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3676}
3677
3678ALIAS (no_set_ipv6_nexthop_local,
3679 no_set_ipv6_nexthop_local_val_cmd,
3680 "no set ipv6 next-hop local X:X::X:X",
3681 NO_STR
3682 SET_STR
3683 IPV6_STR
3684 "IPv6 next-hop address\n"
3685 "IPv6 local address\n"
3686 "IPv6 address of next hop\n")
3687#endif /* HAVE_IPV6 */
3688
3689DEFUN (set_vpnv4_nexthop,
3690 set_vpnv4_nexthop_cmd,
3691 "set vpnv4 next-hop A.B.C.D",
3692 SET_STR
3693 "VPNv4 information\n"
3694 "VPNv4 next-hop address\n"
3695 "IP address of next hop\n")
3696{
3697 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3698}
3699
3700DEFUN (no_set_vpnv4_nexthop,
3701 no_set_vpnv4_nexthop_cmd,
3702 "no set vpnv4 next-hop",
3703 NO_STR
3704 SET_STR
3705 "VPNv4 information\n"
3706 "VPNv4 next-hop address\n")
3707{
3708 if (argc == 0)
3709 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3710
3711 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3712}
3713
3714ALIAS (no_set_vpnv4_nexthop,
3715 no_set_vpnv4_nexthop_val_cmd,
3716 "no set vpnv4 next-hop A.B.C.D",
3717 NO_STR
3718 SET_STR
3719 "VPNv4 information\n"
3720 "VPNv4 next-hop address\n"
3721 "IP address of next hop\n")
3722
3723DEFUN (set_originator_id,
3724 set_originator_id_cmd,
3725 "set originator-id A.B.C.D",
3726 SET_STR
3727 "BGP originator ID attribute\n"
3728 "IP address of originator\n")
3729{
3730 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3731}
3732
3733DEFUN (no_set_originator_id,
3734 no_set_originator_id_cmd,
3735 "no set originator-id",
3736 NO_STR
3737 SET_STR
3738 "BGP originator ID attribute\n")
3739{
3740 if (argc == 0)
3741 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3742
3743 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3744}
3745
3746ALIAS (no_set_originator_id,
3747 no_set_originator_id_val_cmd,
3748 "no set originator-id A.B.C.D",
3749 NO_STR
3750 SET_STR
3751 "BGP originator ID attribute\n"
3752 "IP address of originator\n")
3753
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003754DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003755 set_pathlimit_ttl_cmd,
3756 "set pathlimit ttl <1-255>",
3757 SET_STR
3758 "BGP AS-Pathlimit attribute\n"
3759 "Set AS-Path Hop-count TTL\n")
3760{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003761 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003762}
3763
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003764DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003765 no_set_pathlimit_ttl_cmd,
3766 "no set pathlimit ttl",
3767 NO_STR
3768 SET_STR
3769 "BGP AS-Pathlimit attribute\n"
3770 "Set AS-Path Hop-count TTL\n")
3771{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003772 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003773}
3774
3775ALIAS (no_set_pathlimit_ttl,
3776 no_set_pathlimit_ttl_val_cmd,
3777 "no set pathlimit ttl <1-255>",
3778 NO_STR
3779 MATCH_STR
3780 "BGP AS-Pathlimit attribute\n"
3781 "Set AS-Path Hop-count TTL\n")
3782
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003783DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003784 match_pathlimit_as_cmd,
3785 "match pathlimit as <1-65535>",
3786 MATCH_STR
3787 "BGP AS-Pathlimit attribute\n"
3788 "Match Pathlimit AS number\n")
3789{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003790 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003791}
3792
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003793DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003794 no_match_pathlimit_as_cmd,
3795 "no match pathlimit as",
3796 NO_STR
3797 MATCH_STR
3798 "BGP AS-Pathlimit attribute\n"
3799 "Match Pathlimit AS number\n")
3800{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003801 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003802}
3803
3804ALIAS (no_match_pathlimit_as,
3805 no_match_pathlimit_as_val_cmd,
3806 "no match pathlimit as <1-65535>",
3807 NO_STR
3808 MATCH_STR
3809 "BGP AS-Pathlimit attribute\n"
3810 "Match Pathlimit ASN\n")
3811
David Lamparter6b0655a2014-06-04 06:53:35 +02003812
paul718e3742002-12-13 20:15:29 +00003813/* Initialization of route map. */
3814void
paul94f2b392005-06-28 12:44:16 +00003815bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003816{
3817 route_map_init ();
3818 route_map_init_vty ();
3819 route_map_add_hook (bgp_route_map_update);
3820 route_map_delete_hook (bgp_route_map_update);
3821
paulfee0f4c2004-09-13 05:12:46 +00003822 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003823 route_map_install_match (&route_match_ip_address_cmd);
3824 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003825 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003826 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3827 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003828 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003829 route_map_install_match (&route_match_aspath_cmd);
3830 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003831 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003832 route_map_install_match (&route_match_metric_cmd);
3833 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003834 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003835
3836 route_map_install_set (&route_set_ip_nexthop_cmd);
3837 route_map_install_set (&route_set_local_pref_cmd);
3838 route_map_install_set (&route_set_weight_cmd);
3839 route_map_install_set (&route_set_metric_cmd);
3840 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003841 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003842 route_map_install_set (&route_set_origin_cmd);
3843 route_map_install_set (&route_set_atomic_aggregate_cmd);
3844 route_map_install_set (&route_set_aggregator_as_cmd);
3845 route_map_install_set (&route_set_community_cmd);
3846 route_map_install_set (&route_set_community_delete_cmd);
3847 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3848 route_map_install_set (&route_set_originator_id_cmd);
3849 route_map_install_set (&route_set_ecommunity_rt_cmd);
3850 route_map_install_set (&route_set_ecommunity_soo_cmd);
3851
paulfee0f4c2004-09-13 05:12:46 +00003852 install_element (RMAP_NODE, &match_peer_cmd);
3853 install_element (RMAP_NODE, &match_peer_local_cmd);
3854 install_element (RMAP_NODE, &no_match_peer_cmd);
3855 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3856 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003857 install_element (RMAP_NODE, &match_ip_address_cmd);
3858 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3859 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3860 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3861 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3862 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003863 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3864 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3865 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003866 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3867 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3868 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3869 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3870 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3871 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003872 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3873 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3874 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003875
3876 install_element (RMAP_NODE, &match_aspath_cmd);
3877 install_element (RMAP_NODE, &no_match_aspath_cmd);
3878 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3879 install_element (RMAP_NODE, &match_metric_cmd);
3880 install_element (RMAP_NODE, &no_match_metric_cmd);
3881 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3882 install_element (RMAP_NODE, &match_community_cmd);
3883 install_element (RMAP_NODE, &match_community_exact_cmd);
3884 install_element (RMAP_NODE, &no_match_community_cmd);
3885 install_element (RMAP_NODE, &no_match_community_val_cmd);
3886 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003887 install_element (RMAP_NODE, &match_ecommunity_cmd);
3888 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3889 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003890 install_element (RMAP_NODE, &match_origin_cmd);
3891 install_element (RMAP_NODE, &no_match_origin_cmd);
3892 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003893 install_element (RMAP_NODE, &match_probability_cmd);
3894 install_element (RMAP_NODE, &no_match_probability_cmd);
3895 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003896
3897 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003898 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003899 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3900 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3901 install_element (RMAP_NODE, &set_local_pref_cmd);
3902 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3903 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3904 install_element (RMAP_NODE, &set_weight_cmd);
3905 install_element (RMAP_NODE, &no_set_weight_cmd);
3906 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3907 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003908 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003909 install_element (RMAP_NODE, &no_set_metric_cmd);
3910 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3911 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003912 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003913 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3914 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003915 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3916 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003917 install_element (RMAP_NODE, &set_origin_cmd);
3918 install_element (RMAP_NODE, &no_set_origin_cmd);
3919 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3920 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3921 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3922 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3923 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3924 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3925 install_element (RMAP_NODE, &set_community_cmd);
3926 install_element (RMAP_NODE, &set_community_none_cmd);
3927 install_element (RMAP_NODE, &no_set_community_cmd);
3928 install_element (RMAP_NODE, &no_set_community_val_cmd);
3929 install_element (RMAP_NODE, &no_set_community_none_cmd);
3930 install_element (RMAP_NODE, &set_community_delete_cmd);
3931 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3932 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3933 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3934 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3935 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3936 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3937 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3938 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3939 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3940 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3941 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3942 install_element (RMAP_NODE, &set_originator_id_cmd);
3943 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3944 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3945
3946#ifdef HAVE_IPV6
3947 route_map_install_match (&route_match_ipv6_address_cmd);
3948 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3949 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3950 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3951 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003952
paul718e3742002-12-13 20:15:29 +00003953 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3954 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3955 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3956 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3957 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3958 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3959 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3960 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3961 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3962 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3963 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3964 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3965#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003966
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003967 /* AS-Pathlimit: functionality removed, commands kept for
3968 * compatibility.
3969 */
Paul Jakma41367172007-08-06 15:24:51 +00003970 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3971 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3972 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3973 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3974 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3975 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003976}