blob: 36d177d2a7383a939133aaad5c0b8de58489a971 [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
96o Local extention
97
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
paulfee0f4c2004-09-13 05:12:46 +0000104 /* 'match peer (A.B.C.D|X:X::X:X)' */
105
106/* Compares the peer specified in the 'match peer' clause with the peer
107 received in bgp_info->peer. If it is the same, or if the peer structure
108 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000109static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000110route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
111 void *object)
112{
113 union sockunion *su;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200114 union sockunion su_def = { .sa.sa_family = AF_INET,
115 .sin.sin_addr.s_addr = INADDR_ANY };
paulfee0f4c2004-09-13 05:12:46 +0000116 struct peer_group *group;
117 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000118 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000119
120 if (type == RMAP_BGP)
121 {
122 su = rule;
123 peer = ((struct bgp_info *) object)->peer;
124
125 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
126 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
127 return RMAP_NOMATCH;
128
129 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
130 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200131 if (sockunion_same (su, &su_def))
paulfee0f4c2004-09-13 05:12:46 +0000132 {
paul22db9de2005-05-19 01:50:11 +0000133 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000134 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
135 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
136 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000137 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000138 else
paul22db9de2005-05-19 01:50:11 +0000139 ret = RMAP_NOMATCH;
paul22db9de2005-05-19 01:50:11 +0000140 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000141 }
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200142
paulfee0f4c2004-09-13 05:12:46 +0000143 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
144 {
145 if (sockunion_same (su, &peer->su))
146 return RMAP_MATCH;
147
148 return RMAP_NOMATCH;
149 }
150 else
151 {
152 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000153 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000154 {
155 if (sockunion_same (su, &peer->su))
156 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000157 }
Paul Jakma30a22312008-08-15 14:05:22 +0100158 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000159 }
160 }
161 return RMAP_NOMATCH;
162}
163
paul94f2b392005-06-28 12:44:16 +0000164static void *
paulfd79ac92004-10-13 05:06:08 +0000165route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000166{
167 union sockunion *su;
168 int ret;
169
170 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
171
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +0200172 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
paulfee0f4c2004-09-13 05:12:46 +0000173 if (ret < 0) {
174 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
175 return NULL;
176 }
177
178 return su;
179}
180
181/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000182static void
paulfee0f4c2004-09-13 05:12:46 +0000183route_match_peer_free (void *rule)
184{
185 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
186}
187
188/* Route map commands for ip address matching. */
189struct route_map_rule_cmd route_match_peer_cmd =
190{
191 "peer",
192 route_match_peer,
193 route_match_peer_compile,
194 route_match_peer_free
195};
196
paul718e3742002-12-13 20:15:29 +0000197/* `match ip address IP_ACCESS_LIST' */
198
199/* Match function should return 1 if match is success else return
200 zero. */
paul94f2b392005-06-28 12:44:16 +0000201static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000202route_match_ip_address (void *rule, struct prefix *prefix,
203 route_map_object_t type, void *object)
204{
205 struct access_list *alist;
206 /* struct prefix_ipv4 match; */
207
208 if (type == RMAP_BGP)
209 {
210 alist = access_list_lookup (AFI_IP, (char *) rule);
211 if (alist == NULL)
212 return RMAP_NOMATCH;
213
214 return (access_list_apply (alist, prefix) == FILTER_DENY ?
215 RMAP_NOMATCH : RMAP_MATCH);
216 }
217 return RMAP_NOMATCH;
218}
219
220/* Route map `ip address' match statement. `arg' should be
221 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000222static void *
paulfd79ac92004-10-13 05:06:08 +0000223route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000224{
225 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
226}
227
228/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000229static void
paul718e3742002-12-13 20:15:29 +0000230route_match_ip_address_free (void *rule)
231{
232 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
233}
234
235/* Route map commands for ip address matching. */
236struct route_map_rule_cmd route_match_ip_address_cmd =
237{
238 "ip address",
239 route_match_ip_address,
240 route_match_ip_address_compile,
241 route_match_ip_address_free
242};
David Lamparter6b0655a2014-06-04 06:53:35 +0200243
paul718e3742002-12-13 20:15:29 +0000244/* `match ip next-hop IP_ADDRESS' */
245
246/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000247static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000248route_match_ip_next_hop (void *rule, struct prefix *prefix,
249 route_map_object_t type, void *object)
250{
251 struct access_list *alist;
252 struct bgp_info *bgp_info;
253 struct prefix_ipv4 p;
254
255 if (type == RMAP_BGP)
256 {
257 bgp_info = object;
258 p.family = AF_INET;
259 p.prefix = bgp_info->attr->nexthop;
260 p.prefixlen = IPV4_MAX_BITLEN;
261
262 alist = access_list_lookup (AFI_IP, (char *) rule);
263 if (alist == NULL)
264 return RMAP_NOMATCH;
265
266 return (access_list_apply (alist, &p) == FILTER_DENY ?
267 RMAP_NOMATCH : RMAP_MATCH);
268 }
269 return RMAP_NOMATCH;
270}
271
272/* Route map `ip next-hop' match statement. `arg' is
273 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000274static void *
paulfd79ac92004-10-13 05:06:08 +0000275route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000276{
277 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
278}
279
280/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000281static void
paul718e3742002-12-13 20:15:29 +0000282route_match_ip_next_hop_free (void *rule)
283{
284 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
285}
286
287/* Route map commands for ip next-hop matching. */
288struct route_map_rule_cmd route_match_ip_next_hop_cmd =
289{
290 "ip next-hop",
291 route_match_ip_next_hop,
292 route_match_ip_next_hop_compile,
293 route_match_ip_next_hop_free
294};
David Lamparter6b0655a2014-06-04 06:53:35 +0200295
hassoc1643bb2005-02-02 16:43:17 +0000296/* `match ip route-source ACCESS-LIST' */
297
298/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000299static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000300route_match_ip_route_source (void *rule, struct prefix *prefix,
301 route_map_object_t type, void *object)
302{
303 struct access_list *alist;
304 struct bgp_info *bgp_info;
305 struct peer *peer;
306 struct prefix_ipv4 p;
307
308 if (type == RMAP_BGP)
309 {
310 bgp_info = object;
311 peer = bgp_info->peer;
312
313 if (! peer || sockunion_family (&peer->su) != AF_INET)
314 return RMAP_NOMATCH;
315
316 p.family = AF_INET;
317 p.prefix = peer->su.sin.sin_addr;
318 p.prefixlen = IPV4_MAX_BITLEN;
319
320 alist = access_list_lookup (AFI_IP, (char *) rule);
321 if (alist == NULL)
322 return RMAP_NOMATCH;
323
324 return (access_list_apply (alist, &p) == FILTER_DENY ?
325 RMAP_NOMATCH : RMAP_MATCH);
326 }
327 return RMAP_NOMATCH;
328}
329
330/* Route map `ip route-source' match statement. `arg' is
331 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000332static void *
hassoc1643bb2005-02-02 16:43:17 +0000333route_match_ip_route_source_compile (const char *arg)
334{
335 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
336}
337
338/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000339static void
hassoc1643bb2005-02-02 16:43:17 +0000340route_match_ip_route_source_free (void *rule)
341{
342 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
343}
344
345/* Route map commands for ip route-source matching. */
346struct route_map_rule_cmd route_match_ip_route_source_cmd =
347{
348 "ip route-source",
349 route_match_ip_route_source,
350 route_match_ip_route_source_compile,
351 route_match_ip_route_source_free
352};
David Lamparter6b0655a2014-06-04 06:53:35 +0200353
paul718e3742002-12-13 20:15:29 +0000354/* `match ip address prefix-list PREFIX_LIST' */
355
paul94f2b392005-06-28 12:44:16 +0000356static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000357route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
358 route_map_object_t type, void *object)
359{
360 struct prefix_list *plist;
361
362 if (type == RMAP_BGP)
363 {
364 plist = prefix_list_lookup (AFI_IP, (char *) rule);
365 if (plist == NULL)
366 return RMAP_NOMATCH;
367
368 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
369 RMAP_NOMATCH : RMAP_MATCH);
370 }
371 return RMAP_NOMATCH;
372}
373
paul94f2b392005-06-28 12:44:16 +0000374static void *
paulfd79ac92004-10-13 05:06:08 +0000375route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000376{
377 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
378}
379
paul94f2b392005-06-28 12:44:16 +0000380static void
paul718e3742002-12-13 20:15:29 +0000381route_match_ip_address_prefix_list_free (void *rule)
382{
383 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
384}
385
386struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
387{
388 "ip address prefix-list",
389 route_match_ip_address_prefix_list,
390 route_match_ip_address_prefix_list_compile,
391 route_match_ip_address_prefix_list_free
392};
David Lamparter6b0655a2014-06-04 06:53:35 +0200393
paul718e3742002-12-13 20:15:29 +0000394/* `match ip next-hop prefix-list PREFIX_LIST' */
395
paul94f2b392005-06-28 12:44:16 +0000396static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000397route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
398 route_map_object_t type, void *object)
399{
400 struct prefix_list *plist;
401 struct bgp_info *bgp_info;
402 struct prefix_ipv4 p;
403
404 if (type == RMAP_BGP)
405 {
406 bgp_info = object;
407 p.family = AF_INET;
408 p.prefix = bgp_info->attr->nexthop;
409 p.prefixlen = IPV4_MAX_BITLEN;
410
411 plist = prefix_list_lookup (AFI_IP, (char *) rule);
412 if (plist == NULL)
413 return RMAP_NOMATCH;
414
415 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
416 RMAP_NOMATCH : RMAP_MATCH);
417 }
418 return RMAP_NOMATCH;
419}
420
paul94f2b392005-06-28 12:44:16 +0000421static void *
paulfd79ac92004-10-13 05:06:08 +0000422route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000423{
424 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
425}
426
paul94f2b392005-06-28 12:44:16 +0000427static void
paul718e3742002-12-13 20:15:29 +0000428route_match_ip_next_hop_prefix_list_free (void *rule)
429{
430 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
431}
432
433struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
434{
435 "ip next-hop prefix-list",
436 route_match_ip_next_hop_prefix_list,
437 route_match_ip_next_hop_prefix_list_compile,
438 route_match_ip_next_hop_prefix_list_free
439};
David Lamparter6b0655a2014-06-04 06:53:35 +0200440
hassoc1643bb2005-02-02 16:43:17 +0000441/* `match ip route-source prefix-list PREFIX_LIST' */
442
paul94f2b392005-06-28 12:44:16 +0000443static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000444route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
445 route_map_object_t type, void *object)
446{
447 struct prefix_list *plist;
448 struct bgp_info *bgp_info;
449 struct peer *peer;
450 struct prefix_ipv4 p;
451
452 if (type == RMAP_BGP)
453 {
454 bgp_info = object;
455 peer = bgp_info->peer;
456
457 if (! peer || sockunion_family (&peer->su) != AF_INET)
458 return RMAP_NOMATCH;
459
460 p.family = AF_INET;
461 p.prefix = peer->su.sin.sin_addr;
462 p.prefixlen = IPV4_MAX_BITLEN;
463
464 plist = prefix_list_lookup (AFI_IP, (char *) rule);
465 if (plist == NULL)
466 return RMAP_NOMATCH;
467
468 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
469 RMAP_NOMATCH : RMAP_MATCH);
470 }
471 return RMAP_NOMATCH;
472}
473
paul94f2b392005-06-28 12:44:16 +0000474static void *
hassoc1643bb2005-02-02 16:43:17 +0000475route_match_ip_route_source_prefix_list_compile (const char *arg)
476{
477 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
478}
479
paul94f2b392005-06-28 12:44:16 +0000480static void
hassoc1643bb2005-02-02 16:43:17 +0000481route_match_ip_route_source_prefix_list_free (void *rule)
482{
483 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
484}
485
486struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
487{
488 "ip route-source prefix-list",
489 route_match_ip_route_source_prefix_list,
490 route_match_ip_route_source_prefix_list_compile,
491 route_match_ip_route_source_prefix_list_free
492};
David Lamparter6b0655a2014-06-04 06:53:35 +0200493
paul718e3742002-12-13 20:15:29 +0000494/* `match metric METRIC' */
495
496/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000497static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000498route_match_metric (void *rule, struct prefix *prefix,
499 route_map_object_t type, void *object)
500{
501 u_int32_t *med;
502 struct bgp_info *bgp_info;
503
504 if (type == RMAP_BGP)
505 {
506 med = rule;
507 bgp_info = object;
508
509 if (bgp_info->attr->med == *med)
510 return RMAP_MATCH;
511 else
512 return RMAP_NOMATCH;
513 }
514 return RMAP_NOMATCH;
515}
516
517/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000518static void *
paulfd79ac92004-10-13 05:06:08 +0000519route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000520{
521 u_int32_t *med;
522 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000523 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000524
Ulrich Weber664711c2011-12-21 02:24:11 +0400525 /* Metric value shoud be integer. */
526 if (! all_digit (arg))
527 return NULL;
528
529 errno = 0;
paul3b424972003-10-13 09:47:32 +0000530 tmpval = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +0400531 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000532 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000533
paul718e3742002-12-13 20:15:29 +0000534 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000535
536 if (!med)
537 return med;
538
paul3b424972003-10-13 09:47:32 +0000539 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000540 return med;
541}
542
543/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000544static void
paul718e3742002-12-13 20:15:29 +0000545route_match_metric_free (void *rule)
546{
547 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
548}
549
550/* Route map commands for metric matching. */
551struct route_map_rule_cmd route_match_metric_cmd =
552{
553 "metric",
554 route_match_metric,
555 route_match_metric_compile,
556 route_match_metric_free
557};
David Lamparter6b0655a2014-06-04 06:53:35 +0200558
paul718e3742002-12-13 20:15:29 +0000559/* `match as-path ASPATH' */
560
561/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000562static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000563route_match_aspath (void *rule, struct prefix *prefix,
564 route_map_object_t type, void *object)
565{
566
567 struct as_list *as_list;
568 struct bgp_info *bgp_info;
569
570 if (type == RMAP_BGP)
571 {
572 as_list = as_list_lookup ((char *) rule);
573 if (as_list == NULL)
574 return RMAP_NOMATCH;
575
576 bgp_info = object;
577
578 /* Perform match. */
579 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
580 }
581 return RMAP_NOMATCH;
582}
583
584/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000585static void *
paulfd79ac92004-10-13 05:06:08 +0000586route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000587{
588 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
589}
590
591/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000592static void
paul718e3742002-12-13 20:15:29 +0000593route_match_aspath_free (void *rule)
594{
595 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
596}
597
598/* Route map commands for aspath matching. */
599struct route_map_rule_cmd route_match_aspath_cmd =
600{
601 "as-path",
602 route_match_aspath,
603 route_match_aspath_compile,
604 route_match_aspath_free
605};
David Lamparter6b0655a2014-06-04 06:53:35 +0200606
paul718e3742002-12-13 20:15:29 +0000607/* `match community COMMUNIY' */
608struct rmap_community
609{
610 char *name;
611 int exact;
612};
613
614/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000615static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000616route_match_community (void *rule, struct prefix *prefix,
617 route_map_object_t type, void *object)
618{
619 struct community_list *list;
620 struct bgp_info *bgp_info;
621 struct rmap_community *rcom;
622
623 if (type == RMAP_BGP)
624 {
625 bgp_info = object;
626 rcom = rule;
627
hassofee6e4e2005-02-02 16:29:31 +0000628 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000629 if (! list)
630 return RMAP_NOMATCH;
631
632 if (rcom->exact)
633 {
634 if (community_list_exact_match (bgp_info->attr->community, list))
635 return RMAP_MATCH;
636 }
637 else
638 {
639 if (community_list_match (bgp_info->attr->community, list))
640 return RMAP_MATCH;
641 }
642 }
643 return RMAP_NOMATCH;
644}
645
646/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000647static void *
paulfd79ac92004-10-13 05:06:08 +0000648route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000649{
650 struct rmap_community *rcom;
651 int len;
652 char *p;
653
654 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
655
656 p = strchr (arg, ' ');
657 if (p)
658 {
659 len = p - arg;
660 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
661 memcpy (rcom->name, arg, len);
662 rcom->exact = 1;
663 }
664 else
665 {
666 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
667 rcom->exact = 0;
668 }
669 return rcom;
670}
671
672/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000673static void
paul718e3742002-12-13 20:15:29 +0000674route_match_community_free (void *rule)
675{
676 struct rmap_community *rcom = rule;
677
678 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
679 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
680}
681
682/* Route map commands for community matching. */
683struct route_map_rule_cmd route_match_community_cmd =
684{
685 "community",
686 route_match_community,
687 route_match_community_compile,
688 route_match_community_free
689};
David Lamparter6b0655a2014-06-04 06:53:35 +0200690
paul73ffb252003-04-19 15:49:49 +0000691/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000692static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000693route_match_ecommunity (void *rule, struct prefix *prefix,
694 route_map_object_t type, void *object)
695{
696 struct community_list *list;
697 struct bgp_info *bgp_info;
698
699 if (type == RMAP_BGP)
700 {
701 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000702
703 if (!bgp_info->attr->extra)
704 return RMAP_NOMATCH;
705
paul73ffb252003-04-19 15:49:49 +0000706 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000707 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000708 if (! list)
709 return RMAP_NOMATCH;
710
Paul Jakmafb982c22007-05-04 20:15:47 +0000711 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000712 return RMAP_MATCH;
713 }
714 return RMAP_NOMATCH;
715}
716
717/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000718static void *
paulfd79ac92004-10-13 05:06:08 +0000719route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000720{
721 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
722}
723
724/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000725static void
paul73ffb252003-04-19 15:49:49 +0000726route_match_ecommunity_free (void *rule)
727{
728 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
729}
730
731/* Route map commands for community matching. */
732struct route_map_rule_cmd route_match_ecommunity_cmd =
733{
734 "extcommunity",
735 route_match_ecommunity,
736 route_match_ecommunity_compile,
737 route_match_ecommunity_free
738};
David Lamparter6b0655a2014-06-04 06:53:35 +0200739
paul718e3742002-12-13 20:15:29 +0000740/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
741 and `address-family vpnv4'. */
David Lamparter6b0655a2014-06-04 06:53:35 +0200742
paul718e3742002-12-13 20:15:29 +0000743/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000744static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000745route_match_origin (void *rule, struct prefix *prefix,
746 route_map_object_t type, void *object)
747{
748 u_char *origin;
749 struct bgp_info *bgp_info;
750
751 if (type == RMAP_BGP)
752 {
753 origin = rule;
754 bgp_info = object;
755
756 if (bgp_info->attr->origin == *origin)
757 return RMAP_MATCH;
758 }
759
760 return RMAP_NOMATCH;
761}
762
paul94f2b392005-06-28 12:44:16 +0000763static void *
paulfd79ac92004-10-13 05:06:08 +0000764route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000765{
766 u_char *origin;
767
768 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
769
770 if (strcmp (arg, "igp") == 0)
771 *origin = 0;
772 else if (strcmp (arg, "egp") == 0)
773 *origin = 1;
774 else
775 *origin = 2;
776
777 return origin;
778}
779
780/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000781static void
paul718e3742002-12-13 20:15:29 +0000782route_match_origin_free (void *rule)
783{
784 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
785}
786
787/* Route map commands for origin matching. */
788struct route_map_rule_cmd route_match_origin_cmd =
789{
790 "origin",
791 route_match_origin,
792 route_match_origin_compile,
793 route_match_origin_free
794};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400795
796/* match probability { */
797
798static route_map_result_t
799route_match_probability (void *rule, struct prefix *prefix,
800 route_map_object_t type, void *object)
801{
802 long r;
803#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
804 r = random();
805#else
806 r = (long) rand();
807#endif
808
809 switch (*(unsigned *) rule)
810 {
811 case 0: break;
812 case RAND_MAX: return RMAP_MATCH;
813 default:
814 if (r < *(unsigned *) rule)
815 {
816 return RMAP_MATCH;
817 }
818 }
819
820 return RMAP_NOMATCH;
821}
822
823static void *
824route_match_probability_compile (const char *arg)
825{
826 unsigned *lobule;
827 unsigned perc;
828
829#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
830 srandom (time (NULL));
831#else
832 srand (time (NULL));
833#endif
834
835 perc = atoi (arg);
836 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
837
838 switch (perc)
839 {
840 case 0: *lobule = 0; break;
841 case 100: *lobule = RAND_MAX; break;
842 default: *lobule = RAND_MAX / 100 * perc;
843 }
844
845 return lobule;
846}
847
848static void
849route_match_probability_free (void *rule)
850{
851 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
852}
853
854struct route_map_rule_cmd route_match_probability_cmd =
855{
856 "probability",
857 route_match_probability,
858 route_match_probability_compile,
859 route_match_probability_free
860};
861
862/* } */
863
paul718e3742002-12-13 20:15:29 +0000864/* `set ip next-hop IP_ADDRESS' */
865
866/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000867struct rmap_ip_nexthop_set
868{
869 struct in_addr *address;
870 int peer_address;
871};
872
paul94f2b392005-06-28 12:44:16 +0000873static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000874route_set_ip_nexthop (void *rule, struct prefix *prefix,
875 route_map_object_t type, void *object)
876{
paulac41b2a2003-08-12 05:32:27 +0000877 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +0000878 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000879 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000880
881 if (type == RMAP_BGP)
882 {
paul718e3742002-12-13 20:15:29 +0000883 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000884 peer = bgp_info->peer;
885
886 if (rins->peer_address)
887 {
paulfee0f4c2004-09-13 05:12:46 +0000888 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
889 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000890 && peer->su_remote
891 && sockunion_family (peer->su_remote) == AF_INET)
892 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200893 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +0000894 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
895 }
896 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
897 && peer->su_local
898 && sockunion_family (peer->su_local) == AF_INET)
899 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200900 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +0000901 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
902 }
903 }
904 else
905 {
906 /* Set next hop value. */
907 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
908 bgp_info->attr->nexthop = *rins->address;
909 }
paul718e3742002-12-13 20:15:29 +0000910 }
911
912 return RMAP_OKAY;
913}
914
915/* Route map `ip nexthop' compile function. Given string is converted
916 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000917static void *
paulfd79ac92004-10-13 05:06:08 +0000918route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000919{
paulac41b2a2003-08-12 05:32:27 +0000920 struct rmap_ip_nexthop_set *rins;
921 struct in_addr *address = NULL;
922 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000923 int ret;
paul718e3742002-12-13 20:15:29 +0000924
paulac41b2a2003-08-12 05:32:27 +0000925 if (strcmp (arg, "peer-address") == 0)
926 peer_address = 1;
927 else
paul718e3742002-12-13 20:15:29 +0000928 {
paulac41b2a2003-08-12 05:32:27 +0000929 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
930 ret = inet_aton (arg, address);
931
932 if (ret == 0)
933 {
934 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
935 return NULL;
936 }
paul718e3742002-12-13 20:15:29 +0000937 }
938
Stephen Hemminger393deb92008-08-18 14:13:29 -0700939 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000940
941 rins->address = address;
942 rins->peer_address = peer_address;
943
944 return rins;
paul718e3742002-12-13 20:15:29 +0000945}
946
947/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000948static void
paul718e3742002-12-13 20:15:29 +0000949route_set_ip_nexthop_free (void *rule)
950{
paulac41b2a2003-08-12 05:32:27 +0000951 struct rmap_ip_nexthop_set *rins = rule;
952
953 if (rins->address)
954 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
955
956 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000957}
958
959/* Route map commands for ip nexthop set. */
960struct route_map_rule_cmd route_set_ip_nexthop_cmd =
961{
962 "ip next-hop",
963 route_set_ip_nexthop,
964 route_set_ip_nexthop_compile,
965 route_set_ip_nexthop_free
966};
David Lamparter6b0655a2014-06-04 06:53:35 +0200967
paul718e3742002-12-13 20:15:29 +0000968/* `set local-preference LOCAL_PREF' */
969
970/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000971static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000972route_set_local_pref (void *rule, struct prefix *prefix,
973 route_map_object_t type, void *object)
974{
975 u_int32_t *local_pref;
976 struct bgp_info *bgp_info;
977
978 if (type == RMAP_BGP)
979 {
980 /* Fetch routemap's rule information. */
981 local_pref = rule;
982 bgp_info = object;
983
984 /* Set local preference value. */
985 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
986 bgp_info->attr->local_pref = *local_pref;
987 }
988
989 return RMAP_OKAY;
990}
991
992/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000993static void *
paulfd79ac92004-10-13 05:06:08 +0000994route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000995{
paulfd79ac92004-10-13 05:06:08 +0000996 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000997 u_int32_t *local_pref;
998 char *endptr = NULL;
999
1000 /* Local preference value shoud be integer. */
1001 if (! all_digit (arg))
1002 return NULL;
paulfd79ac92004-10-13 05:06:08 +00001003
Ulrich Weber664711c2011-12-21 02:24:11 +04001004 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001005 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001006 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001007 return NULL;
1008
1009 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1010
1011 if (!local_pref)
1012 return local_pref;
1013
1014 *local_pref = tmp;
1015
paul718e3742002-12-13 20:15:29 +00001016 return local_pref;
1017}
1018
1019/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001020static void
paul718e3742002-12-13 20:15:29 +00001021route_set_local_pref_free (void *rule)
1022{
1023 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1024}
1025
1026/* Set local preference rule structure. */
1027struct route_map_rule_cmd route_set_local_pref_cmd =
1028{
1029 "local-preference",
1030 route_set_local_pref,
1031 route_set_local_pref_compile,
1032 route_set_local_pref_free,
1033};
David Lamparter6b0655a2014-06-04 06:53:35 +02001034
paul718e3742002-12-13 20:15:29 +00001035/* `set weight WEIGHT' */
1036
1037/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001038static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001039route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1040 void *object)
1041{
1042 u_int32_t *weight;
1043 struct bgp_info *bgp_info;
1044
1045 if (type == RMAP_BGP)
1046 {
1047 /* Fetch routemap's rule information. */
1048 weight = rule;
1049 bgp_info = object;
1050
1051 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001052 if (*weight)
1053 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1054 else if (bgp_info->attr->extra)
1055 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001056 }
1057
1058 return RMAP_OKAY;
1059}
1060
1061/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001062static void *
paulfd79ac92004-10-13 05:06:08 +00001063route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001064{
paulfd79ac92004-10-13 05:06:08 +00001065 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001066 u_int32_t *weight;
1067 char *endptr = NULL;
1068
1069 /* Local preference value shoud be integer. */
1070 if (! all_digit (arg))
1071 return NULL;
1072
Ulrich Weber664711c2011-12-21 02:24:11 +04001073 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001074 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001075 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001076 return NULL;
1077
paul718e3742002-12-13 20:15:29 +00001078 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001079
1080 if (weight == NULL)
1081 return weight;
1082
1083 *weight = tmp;
1084
paul718e3742002-12-13 20:15:29 +00001085 return weight;
1086}
1087
1088/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001089static void
paul718e3742002-12-13 20:15:29 +00001090route_set_weight_free (void *rule)
1091{
1092 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1093}
1094
1095/* Set local preference rule structure. */
1096struct route_map_rule_cmd route_set_weight_cmd =
1097{
1098 "weight",
1099 route_set_weight,
1100 route_set_weight_compile,
1101 route_set_weight_free,
1102};
David Lamparter6b0655a2014-06-04 06:53:35 +02001103
paul718e3742002-12-13 20:15:29 +00001104/* `set metric METRIC' */
1105
1106/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001107static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001108route_set_metric (void *rule, struct prefix *prefix,
1109 route_map_object_t type, void *object)
1110{
1111 char *metric;
1112 u_int32_t metric_val;
1113 struct bgp_info *bgp_info;
1114
1115 if (type == RMAP_BGP)
1116 {
1117 /* Fetch routemap's rule information. */
1118 metric = rule;
1119 bgp_info = object;
1120
1121 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1122 bgp_info->attr->med = 0;
1123 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1124
1125 if (all_digit (metric))
1126 {
1127 metric_val = strtoul (metric, (char **)NULL, 10);
1128 bgp_info->attr->med = metric_val;
1129 }
1130 else
1131 {
1132 metric_val = strtoul (metric+1, (char **)NULL, 10);
1133
1134 if (strncmp (metric, "+", 1) == 0)
1135 {
paul3b424972003-10-13 09:47:32 +00001136 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1137 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001138 else
paul537d8ea2003-08-27 06:45:32 +00001139 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001140 }
1141 else if (strncmp (metric, "-", 1) == 0)
1142 {
paul537d8ea2003-08-27 06:45:32 +00001143 if (bgp_info->attr->med <= metric_val)
1144 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001145 else
paul537d8ea2003-08-27 06:45:32 +00001146 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001147 }
1148 }
1149 }
1150 return RMAP_OKAY;
1151}
1152
1153/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001154static void *
paulfd79ac92004-10-13 05:06:08 +00001155route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001156{
1157 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001158 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001159 char *endptr = NULL;
1160
1161 if (all_digit (arg))
1162 {
1163 /* set metric value check*/
Ulrich Weber664711c2011-12-21 02:24:11 +04001164 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001165 larg = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001166 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001167 return NULL;
paul94f2b392005-06-28 12:44:16 +00001168 metric = larg;
paul718e3742002-12-13 20:15:29 +00001169 }
1170 else
1171 {
1172 /* set metric +/-value check */
1173 if ((strncmp (arg, "+", 1) != 0
1174 && strncmp (arg, "-", 1) != 0)
1175 || (! all_digit (arg+1)))
1176 return NULL;
1177
Ulrich Weber664711c2011-12-21 02:24:11 +04001178 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001179 larg = strtoul (arg+1, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001180 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001181 return NULL;
paul94f2b392005-06-28 12:44:16 +00001182 metric = larg;
paul718e3742002-12-13 20:15:29 +00001183 }
1184
1185 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1186}
1187
1188/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001189static void
paul718e3742002-12-13 20:15:29 +00001190route_set_metric_free (void *rule)
1191{
1192 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1193}
1194
1195/* Set metric rule structure. */
1196struct route_map_rule_cmd route_set_metric_cmd =
1197{
1198 "metric",
1199 route_set_metric,
1200 route_set_metric_compile,
1201 route_set_metric_free,
1202};
David Lamparter6b0655a2014-06-04 06:53:35 +02001203
paul718e3742002-12-13 20:15:29 +00001204/* `set as-path prepend ASPATH' */
1205
1206/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001207static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001208route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1209{
1210 struct aspath *aspath;
1211 struct aspath *new;
1212 struct bgp_info *binfo;
1213
1214 if (type == RMAP_BGP)
1215 {
1216 aspath = rule;
1217 binfo = object;
1218
1219 if (binfo->attr->aspath->refcnt)
1220 new = aspath_dup (binfo->attr->aspath);
1221 else
1222 new = binfo->attr->aspath;
1223
1224 aspath_prepend (aspath, new);
1225 binfo->attr->aspath = new;
1226 }
1227
1228 return RMAP_OKAY;
1229}
1230
1231/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001232static void *
paulfd79ac92004-10-13 05:06:08 +00001233route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001234{
1235 struct aspath *aspath;
1236
1237 aspath = aspath_str2aspath (arg);
1238 if (! aspath)
1239 return NULL;
1240 return aspath;
1241}
1242
1243/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001244static void
paul718e3742002-12-13 20:15:29 +00001245route_set_aspath_prepend_free (void *rule)
1246{
1247 struct aspath *aspath = rule;
1248 aspath_free (aspath);
1249}
1250
1251/* Set metric rule structure. */
1252struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1253{
1254 "as-path prepend",
1255 route_set_aspath_prepend,
1256 route_set_aspath_prepend_compile,
1257 route_set_aspath_prepend_free,
1258};
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
1285/* FIXME: consider using route_set_aspath_prepend_compile() and
1286 * route_set_aspath_prepend_free(), which two below function are
1287 * exact clones of.
1288 */
1289
1290/* Compile function for as-path exclude. */
1291static void *
1292route_set_aspath_exclude_compile (const char *arg)
1293{
1294 struct aspath *aspath;
1295
1296 aspath = aspath_str2aspath (arg);
1297 if (! aspath)
1298 return NULL;
1299 return aspath;
1300}
1301
1302static void
1303route_set_aspath_exclude_free (void *rule)
1304{
1305 struct aspath *aspath = rule;
1306 aspath_free (aspath);
1307}
1308
1309/* Set ASn exlude rule structure. */
1310struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1311{
1312 "as-path exclude",
1313 route_set_aspath_exclude,
1314 route_set_aspath_exclude_compile,
1315 route_set_aspath_exclude_free,
1316};
David Lamparter6b0655a2014-06-04 06:53:35 +02001317
paul718e3742002-12-13 20:15:29 +00001318/* `set community COMMUNITY' */
1319struct rmap_com_set
1320{
1321 struct community *com;
1322 int additive;
1323 int none;
1324};
1325
1326/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001327static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001328route_set_community (void *rule, struct prefix *prefix,
1329 route_map_object_t type, void *object)
1330{
1331 struct rmap_com_set *rcs;
1332 struct bgp_info *binfo;
1333 struct attr *attr;
1334 struct community *new = NULL;
1335 struct community *old;
1336 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001337
paul718e3742002-12-13 20:15:29 +00001338 if (type == RMAP_BGP)
1339 {
1340 rcs = rule;
1341 binfo = object;
1342 attr = binfo->attr;
1343 old = attr->community;
1344
1345 /* "none" case. */
1346 if (rcs->none)
1347 {
1348 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1349 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001350 /* See the longer comment down below. */
1351 if (old && old->refcnt == 0)
1352 community_free(old);
paul718e3742002-12-13 20:15:29 +00001353 return RMAP_OKAY;
1354 }
1355
1356 /* "additive" case. */
1357 if (rcs->additive && old)
1358 {
1359 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001360
1361 /* HACK: if the old community is not intern'd,
1362 * we should free it here, or all reference to it may be lost.
1363 * Really need to cleanup attribute caching sometime.
1364 */
1365 if (old->refcnt == 0)
1366 community_free (old);
paul718e3742002-12-13 20:15:29 +00001367 new = community_uniq_sort (merge);
1368 community_free (merge);
1369 }
1370 else
1371 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001372
1373 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001374 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001375
paul718e3742002-12-13 20:15:29 +00001376 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1377 }
1378
1379 return RMAP_OKAY;
1380}
1381
1382/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001383static void *
paulfd79ac92004-10-13 05:06:08 +00001384route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001385{
1386 struct rmap_com_set *rcs;
1387 struct community *com = NULL;
1388 char *sp;
1389 int additive = 0;
1390 int none = 0;
1391
1392 if (strcmp (arg, "none") == 0)
1393 none = 1;
1394 else
1395 {
1396 sp = strstr (arg, "additive");
1397
1398 if (sp && sp > arg)
1399 {
1400 /* "additive" keyworkd is included. */
1401 additive = 1;
1402 *(sp - 1) = '\0';
1403 }
1404
1405 com = community_str2com (arg);
1406
1407 if (additive)
1408 *(sp - 1) = ' ';
1409
1410 if (! com)
1411 return NULL;
1412 }
1413
Stephen Hemminger393deb92008-08-18 14:13:29 -07001414 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001415 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001416 rcs->additive = additive;
1417 rcs->none = none;
1418
1419 return rcs;
1420}
1421
1422/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001423static void
paul718e3742002-12-13 20:15:29 +00001424route_set_community_free (void *rule)
1425{
1426 struct rmap_com_set *rcs = rule;
1427
1428 if (rcs->com)
1429 community_free (rcs->com);
1430 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1431}
1432
1433/* Set community rule structure. */
1434struct route_map_rule_cmd route_set_community_cmd =
1435{
1436 "community",
1437 route_set_community,
1438 route_set_community_compile,
1439 route_set_community_free,
1440};
David Lamparter6b0655a2014-06-04 06:53:35 +02001441
hassofee6e4e2005-02-02 16:29:31 +00001442/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001443
1444/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001445static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001446route_set_community_delete (void *rule, struct prefix *prefix,
1447 route_map_object_t type, void *object)
1448{
1449 struct community_list *list;
1450 struct community *merge;
1451 struct community *new;
1452 struct community *old;
1453 struct bgp_info *binfo;
1454
1455 if (type == RMAP_BGP)
1456 {
1457 if (! rule)
1458 return RMAP_OKAY;
1459
1460 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001461 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001462 old = binfo->attr->community;
1463
1464 if (list && old)
1465 {
1466 merge = community_list_match_delete (community_dup (old), list);
1467 new = community_uniq_sort (merge);
1468 community_free (merge);
1469
Michael Lambert604a9b42010-09-13 11:48:11 -04001470 /* HACK: if the old community is not intern'd,
1471 * we should free it here, or all reference to it may be lost.
1472 * Really need to cleanup attribute caching sometime.
1473 */
1474 if (old->refcnt == 0)
1475 community_free (old);
1476
paul718e3742002-12-13 20:15:29 +00001477 if (new->size == 0)
1478 {
1479 binfo->attr->community = NULL;
1480 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1481 community_free (new);
1482 }
1483 else
1484 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001485 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001486 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1487 }
1488 }
1489 }
1490
1491 return RMAP_OKAY;
1492}
1493
1494/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001495static void *
paulfd79ac92004-10-13 05:06:08 +00001496route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001497{
1498 char *p;
1499 char *str;
1500 int len;
1501
1502 p = strchr (arg, ' ');
1503 if (p)
1504 {
1505 len = p - arg;
1506 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1507 memcpy (str, arg, len);
1508 }
1509 else
1510 str = NULL;
1511
1512 return str;
1513}
1514
1515/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001516static void
paul718e3742002-12-13 20:15:29 +00001517route_set_community_delete_free (void *rule)
1518{
1519 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1520}
1521
1522/* Set community rule structure. */
1523struct route_map_rule_cmd route_set_community_delete_cmd =
1524{
1525 "comm-list",
1526 route_set_community_delete,
1527 route_set_community_delete_compile,
1528 route_set_community_delete_free,
1529};
David Lamparter6b0655a2014-06-04 06:53:35 +02001530
paul718e3742002-12-13 20:15:29 +00001531/* `set extcommunity rt COMMUNITY' */
1532
David Lamparter73d78ea2014-06-04 00:58:47 +02001533/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001534static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001535route_set_ecommunity (void *rule, struct prefix *prefix,
1536 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001537{
1538 struct ecommunity *ecom;
1539 struct ecommunity *new_ecom;
1540 struct ecommunity *old_ecom;
1541 struct bgp_info *bgp_info;
1542
1543 if (type == RMAP_BGP)
1544 {
1545 ecom = rule;
1546 bgp_info = object;
1547
1548 if (! ecom)
1549 return RMAP_OKAY;
1550
1551 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001552 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001553
1554 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001555 {
1556 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1557
1558 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1559 * ->refcnt = 0 => set by a previous route-map statement */
1560 if (!old_ecom->refcnt)
1561 ecommunity_free (&old_ecom);
1562 }
paul718e3742002-12-13 20:15:29 +00001563 else
1564 new_ecom = ecommunity_dup (ecom);
1565
David Lamparter27bf90a2014-06-04 00:59:01 +02001566 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1567 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001568
paul718e3742002-12-13 20:15:29 +00001569 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1570 }
1571 return RMAP_OKAY;
1572}
1573
1574/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001575static void *
paulfd79ac92004-10-13 05:06:08 +00001576route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001577{
1578 struct ecommunity *ecom;
1579
1580 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1581 if (! ecom)
1582 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001583 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001584}
1585
David Lamparter73d78ea2014-06-04 00:58:47 +02001586/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001587static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001588route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001589{
1590 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001591 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001592}
1593
1594/* Set community rule structure. */
1595struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1596{
1597 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001598 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001599 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001600 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001601};
1602
1603/* `set extcommunity soo COMMUNITY' */
1604
paul718e3742002-12-13 20:15:29 +00001605/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001606static void *
paulfd79ac92004-10-13 05:06:08 +00001607route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001608{
1609 struct ecommunity *ecom;
1610
1611 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1612 if (! ecom)
1613 return NULL;
1614
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001615 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001616}
1617
paul718e3742002-12-13 20:15:29 +00001618/* Set community rule structure. */
1619struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1620{
1621 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001622 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001623 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001624 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001625};
David Lamparter6b0655a2014-06-04 06:53:35 +02001626
paul718e3742002-12-13 20:15:29 +00001627/* `set origin ORIGIN' */
1628
1629/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001630static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001631route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1632{
1633 u_char *origin;
1634 struct bgp_info *bgp_info;
1635
1636 if (type == RMAP_BGP)
1637 {
1638 origin = rule;
1639 bgp_info = object;
1640
1641 bgp_info->attr->origin = *origin;
1642 }
1643
1644 return RMAP_OKAY;
1645}
1646
1647/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001648static void *
paulfd79ac92004-10-13 05:06:08 +00001649route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001650{
1651 u_char *origin;
1652
1653 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1654
1655 if (strcmp (arg, "igp") == 0)
1656 *origin = 0;
1657 else if (strcmp (arg, "egp") == 0)
1658 *origin = 1;
1659 else
1660 *origin = 2;
1661
1662 return origin;
1663}
1664
1665/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001666static void
paul718e3742002-12-13 20:15:29 +00001667route_set_origin_free (void *rule)
1668{
1669 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1670}
1671
1672/* Set metric rule structure. */
1673struct route_map_rule_cmd route_set_origin_cmd =
1674{
1675 "origin",
1676 route_set_origin,
1677 route_set_origin_compile,
1678 route_set_origin_free,
1679};
David Lamparter6b0655a2014-06-04 06:53:35 +02001680
paul718e3742002-12-13 20:15:29 +00001681/* `set atomic-aggregate' */
1682
1683/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001684static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001685route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1686 route_map_object_t type, void *object)
1687{
1688 struct bgp_info *bgp_info;
1689
1690 if (type == RMAP_BGP)
1691 {
1692 bgp_info = object;
1693 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1694 }
1695
1696 return RMAP_OKAY;
1697}
1698
1699/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001700static void *
paulfd79ac92004-10-13 05:06:08 +00001701route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001702{
1703 return (void *)1;
1704}
1705
1706/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001707static void
paul718e3742002-12-13 20:15:29 +00001708route_set_atomic_aggregate_free (void *rule)
1709{
1710 return;
1711}
1712
1713/* Set atomic aggregate rule structure. */
1714struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1715{
1716 "atomic-aggregate",
1717 route_set_atomic_aggregate,
1718 route_set_atomic_aggregate_compile,
1719 route_set_atomic_aggregate_free,
1720};
David Lamparter6b0655a2014-06-04 06:53:35 +02001721
paul718e3742002-12-13 20:15:29 +00001722/* `set aggregator as AS A.B.C.D' */
1723struct aggregator
1724{
1725 as_t as;
1726 struct in_addr address;
1727};
1728
paul94f2b392005-06-28 12:44:16 +00001729static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001730route_set_aggregator_as (void *rule, struct prefix *prefix,
1731 route_map_object_t type, void *object)
1732{
1733 struct bgp_info *bgp_info;
1734 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001735 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001736
1737 if (type == RMAP_BGP)
1738 {
1739 bgp_info = object;
1740 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001741 ae = bgp_attr_extra_get (bgp_info->attr);
1742
1743 ae->aggregator_as = aggregator->as;
1744 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001745 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1746 }
1747
1748 return RMAP_OKAY;
1749}
1750
paul94f2b392005-06-28 12:44:16 +00001751static void *
paulfd79ac92004-10-13 05:06:08 +00001752route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001753{
1754 struct aggregator *aggregator;
1755 char as[10];
1756 char address[20];
1757
Stephen Hemminger393deb92008-08-18 14:13:29 -07001758 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001759 sscanf (arg, "%s %s", as, address);
1760
1761 aggregator->as = strtoul (as, NULL, 10);
1762 inet_aton (address, &aggregator->address);
1763
1764 return aggregator;
1765}
1766
paul94f2b392005-06-28 12:44:16 +00001767static void
paul718e3742002-12-13 20:15:29 +00001768route_set_aggregator_as_free (void *rule)
1769{
1770 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1771}
1772
1773struct route_map_rule_cmd route_set_aggregator_as_cmd =
1774{
1775 "aggregator as",
1776 route_set_aggregator_as,
1777 route_set_aggregator_as_compile,
1778 route_set_aggregator_as_free,
1779};
David Lamparter6b0655a2014-06-04 06:53:35 +02001780
paul718e3742002-12-13 20:15:29 +00001781#ifdef HAVE_IPV6
1782/* `match ipv6 address IP_ACCESS_LIST' */
1783
paul94f2b392005-06-28 12:44:16 +00001784static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001785route_match_ipv6_address (void *rule, struct prefix *prefix,
1786 route_map_object_t type, void *object)
1787{
1788 struct access_list *alist;
1789
1790 if (type == RMAP_BGP)
1791 {
1792 alist = access_list_lookup (AFI_IP6, (char *) rule);
1793 if (alist == NULL)
1794 return RMAP_NOMATCH;
1795
1796 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1797 RMAP_NOMATCH : RMAP_MATCH);
1798 }
1799 return RMAP_NOMATCH;
1800}
1801
paul94f2b392005-06-28 12:44:16 +00001802static void *
paulfd79ac92004-10-13 05:06:08 +00001803route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001804{
1805 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1806}
1807
paul94f2b392005-06-28 12:44:16 +00001808static void
paul718e3742002-12-13 20:15:29 +00001809route_match_ipv6_address_free (void *rule)
1810{
1811 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1812}
1813
1814/* Route map commands for ip address matching. */
1815struct route_map_rule_cmd route_match_ipv6_address_cmd =
1816{
1817 "ipv6 address",
1818 route_match_ipv6_address,
1819 route_match_ipv6_address_compile,
1820 route_match_ipv6_address_free
1821};
David Lamparter6b0655a2014-06-04 06:53:35 +02001822
paul718e3742002-12-13 20:15:29 +00001823/* `match ipv6 next-hop IP_ADDRESS' */
1824
paul94f2b392005-06-28 12:44:16 +00001825static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001826route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1827 route_map_object_t type, void *object)
1828{
1829 struct in6_addr *addr;
1830 struct bgp_info *bgp_info;
1831
1832 if (type == RMAP_BGP)
1833 {
1834 addr = rule;
1835 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001836
1837 if (!bgp_info->attr->extra)
1838 return RMAP_NOMATCH;
1839
1840 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001841 return RMAP_MATCH;
1842
Paul Jakmafb982c22007-05-04 20:15:47 +00001843 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1844 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001845 return RMAP_MATCH;
1846
1847 return RMAP_NOMATCH;
1848 }
1849
1850 return RMAP_NOMATCH;
1851}
1852
paul94f2b392005-06-28 12:44:16 +00001853static void *
paulfd79ac92004-10-13 05:06:08 +00001854route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001855{
1856 struct in6_addr *address;
1857 int ret;
1858
1859 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1860
1861 ret = inet_pton (AF_INET6, arg, address);
1862 if (!ret)
1863 {
1864 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1865 return NULL;
1866 }
1867
1868 return address;
1869}
1870
paul94f2b392005-06-28 12:44:16 +00001871static void
paul718e3742002-12-13 20:15:29 +00001872route_match_ipv6_next_hop_free (void *rule)
1873{
1874 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1875}
1876
1877struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1878{
1879 "ipv6 next-hop",
1880 route_match_ipv6_next_hop,
1881 route_match_ipv6_next_hop_compile,
1882 route_match_ipv6_next_hop_free
1883};
David Lamparter6b0655a2014-06-04 06:53:35 +02001884
paul718e3742002-12-13 20:15:29 +00001885/* `match ipv6 address prefix-list PREFIX_LIST' */
1886
paul94f2b392005-06-28 12:44:16 +00001887static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001888route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1889 route_map_object_t type, void *object)
1890{
1891 struct prefix_list *plist;
1892
1893 if (type == RMAP_BGP)
1894 {
1895 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1896 if (plist == NULL)
1897 return RMAP_NOMATCH;
1898
1899 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1900 RMAP_NOMATCH : RMAP_MATCH);
1901 }
1902 return RMAP_NOMATCH;
1903}
1904
paul94f2b392005-06-28 12:44:16 +00001905static void *
paulfd79ac92004-10-13 05:06:08 +00001906route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001907{
1908 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1909}
1910
paul94f2b392005-06-28 12:44:16 +00001911static void
paul718e3742002-12-13 20:15:29 +00001912route_match_ipv6_address_prefix_list_free (void *rule)
1913{
1914 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1915}
1916
1917struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1918{
1919 "ipv6 address prefix-list",
1920 route_match_ipv6_address_prefix_list,
1921 route_match_ipv6_address_prefix_list_compile,
1922 route_match_ipv6_address_prefix_list_free
1923};
David Lamparter6b0655a2014-06-04 06:53:35 +02001924
paul718e3742002-12-13 20:15:29 +00001925/* `set ipv6 nexthop global IP_ADDRESS' */
1926
1927/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001928static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001929route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1930 route_map_object_t type, void *object)
1931{
1932 struct in6_addr *address;
1933 struct bgp_info *bgp_info;
1934
1935 if (type == RMAP_BGP)
1936 {
1937 /* Fetch routemap's rule information. */
1938 address = rule;
1939 bgp_info = object;
1940
1941 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001942 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001943
1944 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001945 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1946 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001947 }
1948
1949 return RMAP_OKAY;
1950}
1951
1952/* Route map `ip next-hop' compile function. Given string is converted
1953 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001954static void *
paulfd79ac92004-10-13 05:06:08 +00001955route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001956{
1957 int ret;
1958 struct in6_addr *address;
1959
1960 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1961
1962 ret = inet_pton (AF_INET6, arg, address);
1963
1964 if (ret == 0)
1965 {
1966 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1967 return NULL;
1968 }
1969
1970 return address;
1971}
1972
1973/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001974static void
paul718e3742002-12-13 20:15:29 +00001975route_set_ipv6_nexthop_global_free (void *rule)
1976{
1977 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1978}
1979
1980/* Route map commands for ip nexthop set. */
1981struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1982{
1983 "ipv6 next-hop global",
1984 route_set_ipv6_nexthop_global,
1985 route_set_ipv6_nexthop_global_compile,
1986 route_set_ipv6_nexthop_global_free
1987};
David Lamparter6b0655a2014-06-04 06:53:35 +02001988
paul718e3742002-12-13 20:15:29 +00001989/* `set ipv6 nexthop local IP_ADDRESS' */
1990
1991/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001992static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001993route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1994 route_map_object_t type, void *object)
1995{
1996 struct in6_addr *address;
1997 struct bgp_info *bgp_info;
1998
1999 if (type == RMAP_BGP)
2000 {
2001 /* Fetch routemap's rule information. */
2002 address = rule;
2003 bgp_info = object;
2004
2005 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002006 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002007
2008 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002009 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2010 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002011 }
2012
2013 return RMAP_OKAY;
2014}
2015
2016/* Route map `ip nexthop' compile function. Given string is converted
2017 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002018static void *
paulfd79ac92004-10-13 05:06:08 +00002019route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002020{
2021 int ret;
2022 struct in6_addr *address;
2023
2024 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2025
2026 ret = inet_pton (AF_INET6, arg, address);
2027
2028 if (ret == 0)
2029 {
2030 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2031 return NULL;
2032 }
2033
2034 return address;
2035}
2036
2037/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002038static void
paul718e3742002-12-13 20:15:29 +00002039route_set_ipv6_nexthop_local_free (void *rule)
2040{
2041 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2042}
2043
2044/* Route map commands for ip nexthop set. */
2045struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2046{
2047 "ipv6 next-hop local",
2048 route_set_ipv6_nexthop_local,
2049 route_set_ipv6_nexthop_local_compile,
2050 route_set_ipv6_nexthop_local_free
2051};
2052#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02002053
paul718e3742002-12-13 20:15:29 +00002054/* `set vpnv4 nexthop A.B.C.D' */
2055
paul94f2b392005-06-28 12:44:16 +00002056static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002057route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2058 route_map_object_t type, void *object)
2059{
2060 struct in_addr *address;
2061 struct bgp_info *bgp_info;
2062
2063 if (type == RMAP_BGP)
2064 {
2065 /* Fetch routemap's rule information. */
2066 address = rule;
2067 bgp_info = object;
2068
2069 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002070 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002071 }
2072
2073 return RMAP_OKAY;
2074}
2075
paul94f2b392005-06-28 12:44:16 +00002076static void *
paulfd79ac92004-10-13 05:06:08 +00002077route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002078{
2079 int ret;
2080 struct in_addr *address;
2081
2082 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2083
2084 ret = inet_aton (arg, address);
2085
2086 if (ret == 0)
2087 {
2088 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2089 return NULL;
2090 }
2091
2092 return address;
2093}
2094
paul94f2b392005-06-28 12:44:16 +00002095static void
paul718e3742002-12-13 20:15:29 +00002096route_set_vpnv4_nexthop_free (void *rule)
2097{
2098 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2099}
2100
2101/* Route map commands for ip nexthop set. */
2102struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2103{
2104 "vpnv4 next-hop",
2105 route_set_vpnv4_nexthop,
2106 route_set_vpnv4_nexthop_compile,
2107 route_set_vpnv4_nexthop_free
2108};
David Lamparter6b0655a2014-06-04 06:53:35 +02002109
paul718e3742002-12-13 20:15:29 +00002110/* `set originator-id' */
2111
2112/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002113static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002114route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2115{
2116 struct in_addr *address;
2117 struct bgp_info *bgp_info;
2118
2119 if (type == RMAP_BGP)
2120 {
2121 address = rule;
2122 bgp_info = object;
2123
2124 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002125 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002126 }
2127
2128 return RMAP_OKAY;
2129}
2130
2131/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002132static void *
paulfd79ac92004-10-13 05:06:08 +00002133route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002134{
2135 int ret;
2136 struct in_addr *address;
2137
2138 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2139
2140 ret = inet_aton (arg, address);
2141
2142 if (ret == 0)
2143 {
2144 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2145 return NULL;
2146 }
2147
2148 return address;
2149}
2150
2151/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002152static void
paul718e3742002-12-13 20:15:29 +00002153route_set_originator_id_free (void *rule)
2154{
2155 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2156}
2157
2158/* Set metric rule structure. */
2159struct route_map_rule_cmd route_set_originator_id_cmd =
2160{
2161 "originator-id",
2162 route_set_originator_id,
2163 route_set_originator_id_compile,
2164 route_set_originator_id_free,
2165};
David Lamparter6b0655a2014-06-04 06:53:35 +02002166
paul718e3742002-12-13 20:15:29 +00002167/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002168static int
paul718e3742002-12-13 20:15:29 +00002169bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002170 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002171{
2172 int ret;
2173
2174 ret = route_map_add_match (index, command, arg);
2175 if (ret)
2176 {
2177 switch (ret)
2178 {
2179 case RMAP_RULE_MISSING:
2180 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2181 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002182 case RMAP_COMPILE_ERROR:
2183 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2184 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002185 }
2186 }
2187 return CMD_SUCCESS;
2188}
2189
2190/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002191static int
paul718e3742002-12-13 20:15:29 +00002192bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002193 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002194{
2195 int ret;
2196
2197 ret = route_map_delete_match (index, command, arg);
2198 if (ret)
2199 {
2200 switch (ret)
2201 {
2202 case RMAP_RULE_MISSING:
2203 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2204 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002205 case RMAP_COMPILE_ERROR:
2206 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2207 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002208 }
2209 }
2210 return CMD_SUCCESS;
2211}
2212
2213/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002214static int
paul718e3742002-12-13 20:15:29 +00002215bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002216 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002217{
2218 int ret;
2219
2220 ret = route_map_add_set (index, command, arg);
2221 if (ret)
2222 {
2223 switch (ret)
2224 {
2225 case RMAP_RULE_MISSING:
2226 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2227 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002228 case RMAP_COMPILE_ERROR:
2229 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2230 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002231 }
2232 }
2233 return CMD_SUCCESS;
2234}
2235
2236/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002237static int
paul718e3742002-12-13 20:15:29 +00002238bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002239 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002240{
2241 int ret;
2242
2243 ret = route_map_delete_set (index, command, arg);
2244 if (ret)
2245 {
2246 switch (ret)
2247 {
2248 case RMAP_RULE_MISSING:
2249 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2250 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002251 case RMAP_COMPILE_ERROR:
2252 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2253 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002254 }
2255 }
2256 return CMD_SUCCESS;
2257}
2258
2259/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002260static void
paulfd79ac92004-10-13 05:06:08 +00002261bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002262{
2263 int i;
2264 afi_t afi;
2265 safi_t safi;
2266 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002267 struct listnode *node, *nnode;
2268 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002269 struct bgp *bgp;
2270 struct peer *peer;
2271 struct peer_group *group;
2272 struct bgp_filter *filter;
2273 struct bgp_node *bn;
2274 struct bgp_static *bgp_static;
2275
2276 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002277 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002278 {
paul1eb8ef22005-04-07 07:30:20 +00002279 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002280 {
2281 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2282 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2283 {
2284 filter = &peer->filter[afi][safi];
2285
paulfee0f4c2004-09-13 05:12:46 +00002286 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002287 {
2288 if (filter->map[direct].name)
2289 filter->map[direct].map =
2290 route_map_lookup_by_name (filter->map[direct].name);
2291 else
2292 filter->map[direct].map = NULL;
2293 }
2294
2295 if (filter->usmap.name)
2296 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2297 else
2298 filter->usmap.map = NULL;
2299 }
2300 }
paul1eb8ef22005-04-07 07:30:20 +00002301 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002302 {
2303 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2304 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2305 {
2306 filter = &group->conf->filter[afi][safi];
2307
paulfee0f4c2004-09-13 05:12:46 +00002308 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002309 {
2310 if (filter->map[direct].name)
2311 filter->map[direct].map =
2312 route_map_lookup_by_name (filter->map[direct].name);
2313 else
2314 filter->map[direct].map = NULL;
2315 }
2316
2317 if (filter->usmap.name)
2318 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2319 else
2320 filter->usmap.map = NULL;
2321 }
2322 }
2323 }
2324
2325 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002326 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002327 {
paul1eb8ef22005-04-07 07:30:20 +00002328 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002329 {
2330 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2331 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2332 {
2333 if (peer->default_rmap[afi][safi].name)
2334 peer->default_rmap[afi][safi].map =
2335 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2336 else
2337 peer->default_rmap[afi][safi].map = NULL;
2338 }
2339 }
2340 }
2341
2342 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002343 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002344 {
2345 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2346 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2347 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2348 bn = bgp_route_next (bn))
2349 if ((bgp_static = bn->info) != NULL)
2350 {
2351 if (bgp_static->rmap.name)
2352 bgp_static->rmap.map =
2353 route_map_lookup_by_name (bgp_static->rmap.name);
2354 else
2355 bgp_static->rmap.map = NULL;
2356 }
2357 }
2358
2359 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002360 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002361 {
2362 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2363 {
2364 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2365 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2366 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2367#ifdef HAVE_IPV6
2368 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2369 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2370 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2371#endif /* HAVE_IPV6 */
2372 }
2373 }
2374}
David Lamparter6b0655a2014-06-04 06:53:35 +02002375
paulfee0f4c2004-09-13 05:12:46 +00002376DEFUN (match_peer,
2377 match_peer_cmd,
2378 "match peer (A.B.C.D|X:X::X:X)",
2379 MATCH_STR
2380 "Match peer address\n"
2381 "IPv6 address of peer\n"
2382 "IP address of peer\n")
2383{
2384 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2385}
2386
2387DEFUN (match_peer_local,
2388 match_peer_local_cmd,
2389 "match peer local",
2390 MATCH_STR
2391 "Match peer address\n"
2392 "Static or Redistributed routes\n")
2393{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002394 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002395}
2396
2397DEFUN (no_match_peer,
2398 no_match_peer_cmd,
2399 "no match peer",
2400 NO_STR
2401 MATCH_STR
2402 "Match peer address\n")
2403{
2404 if (argc == 0)
2405 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2406
2407 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2408}
2409
2410ALIAS (no_match_peer,
2411 no_match_peer_val_cmd,
2412 "no match peer (A.B.C.D|X:X::X:X)",
2413 NO_STR
2414 MATCH_STR
2415 "Match peer address\n"
2416 "IPv6 address of peer\n"
2417 "IP address of peer\n")
2418
2419ALIAS (no_match_peer,
2420 no_match_peer_local_cmd,
2421 "no match peer local",
2422 NO_STR
2423 MATCH_STR
2424 "Match peer address\n"
2425 "Static or Redistributed routes\n")
2426
paul718e3742002-12-13 20:15:29 +00002427DEFUN (match_ip_address,
2428 match_ip_address_cmd,
2429 "match ip address (<1-199>|<1300-2699>|WORD)",
2430 MATCH_STR
2431 IP_STR
2432 "Match address of route\n"
2433 "IP access-list number\n"
2434 "IP access-list number (expanded range)\n"
2435 "IP Access-list name\n")
2436{
2437 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2438}
2439
2440DEFUN (no_match_ip_address,
2441 no_match_ip_address_cmd,
2442 "no match ip address",
2443 NO_STR
2444 MATCH_STR
2445 IP_STR
2446 "Match address of route\n")
2447{
2448 if (argc == 0)
2449 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2450
2451 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2452}
2453
2454ALIAS (no_match_ip_address,
2455 no_match_ip_address_val_cmd,
2456 "no match ip address (<1-199>|<1300-2699>|WORD)",
2457 NO_STR
2458 MATCH_STR
2459 IP_STR
2460 "Match address of route\n"
2461 "IP access-list number\n"
2462 "IP access-list number (expanded range)\n"
2463 "IP Access-list name\n")
2464
2465DEFUN (match_ip_next_hop,
2466 match_ip_next_hop_cmd,
2467 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2468 MATCH_STR
2469 IP_STR
2470 "Match next-hop address of route\n"
2471 "IP access-list number\n"
2472 "IP access-list number (expanded range)\n"
2473 "IP Access-list name\n")
2474{
2475 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2476}
2477
2478DEFUN (no_match_ip_next_hop,
2479 no_match_ip_next_hop_cmd,
2480 "no match ip next-hop",
2481 NO_STR
2482 MATCH_STR
2483 IP_STR
2484 "Match next-hop address of route\n")
2485{
2486 if (argc == 0)
2487 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2488
2489 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2490}
2491
2492ALIAS (no_match_ip_next_hop,
2493 no_match_ip_next_hop_val_cmd,
2494 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2495 NO_STR
2496 MATCH_STR
2497 IP_STR
2498 "Match next-hop address of route\n"
2499 "IP access-list number\n"
2500 "IP access-list number (expanded range)\n"
2501 "IP Access-list name\n")
2502
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002503/* match probability { */
2504
2505DEFUN (match_probability,
2506 match_probability_cmd,
2507 "match probability <0-100>",
2508 MATCH_STR
2509 "Match portion of routes defined by percentage value\n"
2510 "Percentage of routes\n")
2511{
2512 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2513}
2514
2515DEFUN (no_match_probability,
2516 no_match_probability_cmd,
2517 "no match probability",
2518 NO_STR
2519 MATCH_STR
2520 "Match portion of routes defined by percentage value\n")
2521{
2522 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2523}
2524
2525ALIAS (no_match_probability,
2526 no_match_probability_val_cmd,
2527 "no match probability <1-99>",
2528 NO_STR
2529 MATCH_STR
2530 "Match portion of routes defined by percentage value\n"
2531 "Percentage of routes\n")
2532
2533/* } */
2534
hassoc1643bb2005-02-02 16:43:17 +00002535DEFUN (match_ip_route_source,
2536 match_ip_route_source_cmd,
2537 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2538 MATCH_STR
2539 IP_STR
2540 "Match advertising source address of route\n"
2541 "IP access-list number\n"
2542 "IP access-list number (expanded range)\n"
2543 "IP standard access-list name\n")
2544{
2545 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2546}
2547
2548DEFUN (no_match_ip_route_source,
2549 no_match_ip_route_source_cmd,
2550 "no match ip route-source",
2551 NO_STR
2552 MATCH_STR
2553 IP_STR
2554 "Match advertising source address of route\n")
2555{
2556 if (argc == 0)
2557 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2558
2559 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2560}
2561
2562ALIAS (no_match_ip_route_source,
2563 no_match_ip_route_source_val_cmd,
2564 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2565 NO_STR
2566 MATCH_STR
2567 IP_STR
2568 "Match advertising source address of route\n"
2569 "IP access-list number\n"
2570 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002571 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002572
paul718e3742002-12-13 20:15:29 +00002573DEFUN (match_ip_address_prefix_list,
2574 match_ip_address_prefix_list_cmd,
2575 "match ip address prefix-list WORD",
2576 MATCH_STR
2577 IP_STR
2578 "Match address of route\n"
2579 "Match entries of prefix-lists\n"
2580 "IP prefix-list name\n")
2581{
2582 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2583}
2584
2585DEFUN (no_match_ip_address_prefix_list,
2586 no_match_ip_address_prefix_list_cmd,
2587 "no match ip address prefix-list",
2588 NO_STR
2589 MATCH_STR
2590 IP_STR
2591 "Match address of route\n"
2592 "Match entries of prefix-lists\n")
2593{
2594 if (argc == 0)
2595 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2596
2597 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2598}
2599
2600ALIAS (no_match_ip_address_prefix_list,
2601 no_match_ip_address_prefix_list_val_cmd,
2602 "no match ip address prefix-list WORD",
2603 NO_STR
2604 MATCH_STR
2605 IP_STR
2606 "Match address of route\n"
2607 "Match entries of prefix-lists\n"
2608 "IP prefix-list name\n")
2609
2610DEFUN (match_ip_next_hop_prefix_list,
2611 match_ip_next_hop_prefix_list_cmd,
2612 "match ip next-hop prefix-list WORD",
2613 MATCH_STR
2614 IP_STR
2615 "Match next-hop address of route\n"
2616 "Match entries of prefix-lists\n"
2617 "IP prefix-list name\n")
2618{
2619 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2620}
2621
2622DEFUN (no_match_ip_next_hop_prefix_list,
2623 no_match_ip_next_hop_prefix_list_cmd,
2624 "no match ip next-hop prefix-list",
2625 NO_STR
2626 MATCH_STR
2627 IP_STR
2628 "Match next-hop address of route\n"
2629 "Match entries of prefix-lists\n")
2630{
2631 if (argc == 0)
2632 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2633
2634 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2635}
2636
2637ALIAS (no_match_ip_next_hop_prefix_list,
2638 no_match_ip_next_hop_prefix_list_val_cmd,
2639 "no match ip next-hop prefix-list WORD",
2640 NO_STR
2641 MATCH_STR
2642 IP_STR
2643 "Match next-hop address of route\n"
2644 "Match entries of prefix-lists\n"
2645 "IP prefix-list name\n")
2646
hassoc1643bb2005-02-02 16:43:17 +00002647DEFUN (match_ip_route_source_prefix_list,
2648 match_ip_route_source_prefix_list_cmd,
2649 "match ip route-source prefix-list WORD",
2650 MATCH_STR
2651 IP_STR
2652 "Match advertising source address of route\n"
2653 "Match entries of prefix-lists\n"
2654 "IP prefix-list name\n")
2655{
2656 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2657}
2658
2659DEFUN (no_match_ip_route_source_prefix_list,
2660 no_match_ip_route_source_prefix_list_cmd,
2661 "no match ip route-source prefix-list",
2662 NO_STR
2663 MATCH_STR
2664 IP_STR
2665 "Match advertising source address of route\n"
2666 "Match entries of prefix-lists\n")
2667{
2668 if (argc == 0)
2669 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2670
2671 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2672}
2673
2674ALIAS (no_match_ip_route_source_prefix_list,
2675 no_match_ip_route_source_prefix_list_val_cmd,
2676 "no match ip route-source prefix-list WORD",
2677 NO_STR
2678 MATCH_STR
2679 IP_STR
2680 "Match advertising source address of route\n"
2681 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002682 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002683
paul718e3742002-12-13 20:15:29 +00002684DEFUN (match_metric,
2685 match_metric_cmd,
2686 "match metric <0-4294967295>",
2687 MATCH_STR
2688 "Match metric of route\n"
2689 "Metric value\n")
2690{
2691 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2692}
2693
2694DEFUN (no_match_metric,
2695 no_match_metric_cmd,
2696 "no match metric",
2697 NO_STR
2698 MATCH_STR
2699 "Match metric of route\n")
2700{
2701 if (argc == 0)
2702 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2703
2704 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2705}
2706
2707ALIAS (no_match_metric,
2708 no_match_metric_val_cmd,
2709 "no match metric <0-4294967295>",
2710 NO_STR
2711 MATCH_STR
2712 "Match metric of route\n"
2713 "Metric value\n")
2714
2715DEFUN (match_community,
2716 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002717 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002718 MATCH_STR
2719 "Match BGP community list\n"
2720 "Community-list number (standard)\n"
2721 "Community-list number (expanded)\n"
2722 "Community-list name\n")
2723{
2724 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2725}
2726
2727DEFUN (match_community_exact,
2728 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002729 "match community (<1-99>|<100-500>|WORD) exact-match",
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 "Do exact matching of communities\n")
2736{
2737 int ret;
2738 char *argstr;
2739
2740 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2741 strlen (argv[0]) + strlen ("exact-match") + 2);
2742
2743 sprintf (argstr, "%s exact-match", argv[0]);
2744
2745 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2746
2747 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2748
2749 return ret;
2750}
2751
2752DEFUN (no_match_community,
2753 no_match_community_cmd,
2754 "no match community",
2755 NO_STR
2756 MATCH_STR
2757 "Match BGP community list\n")
2758{
2759 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2760}
2761
2762ALIAS (no_match_community,
2763 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002764 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002765 NO_STR
2766 MATCH_STR
2767 "Match BGP community list\n"
2768 "Community-list number (standard)\n"
2769 "Community-list number (expanded)\n"
2770 "Community-list name\n")
2771
2772ALIAS (no_match_community,
2773 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002774 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002775 NO_STR
2776 MATCH_STR
2777 "Match BGP community list\n"
2778 "Community-list number (standard)\n"
2779 "Community-list number (expanded)\n"
2780 "Community-list name\n"
2781 "Do exact matching of communities\n")
2782
paul73ffb252003-04-19 15:49:49 +00002783DEFUN (match_ecommunity,
2784 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002785 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002786 MATCH_STR
2787 "Match BGP/VPN extended community list\n"
2788 "Extended community-list number (standard)\n"
2789 "Extended community-list number (expanded)\n"
2790 "Extended community-list name\n")
2791{
2792 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2793}
2794
2795DEFUN (no_match_ecommunity,
2796 no_match_ecommunity_cmd,
2797 "no match extcommunity",
2798 NO_STR
2799 MATCH_STR
2800 "Match BGP/VPN extended community list\n")
2801{
2802 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2803}
2804
2805ALIAS (no_match_ecommunity,
2806 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002807 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002808 NO_STR
2809 MATCH_STR
2810 "Match BGP/VPN extended community list\n"
2811 "Extended community-list number (standard)\n"
2812 "Extended community-list number (expanded)\n"
2813 "Extended community-list name\n")
2814
paul718e3742002-12-13 20:15:29 +00002815DEFUN (match_aspath,
2816 match_aspath_cmd,
2817 "match as-path WORD",
2818 MATCH_STR
2819 "Match BGP AS path list\n"
2820 "AS path access-list name\n")
2821{
2822 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2823}
2824
2825DEFUN (no_match_aspath,
2826 no_match_aspath_cmd,
2827 "no match as-path",
2828 NO_STR
2829 MATCH_STR
2830 "Match BGP AS path list\n")
2831{
2832 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2833}
2834
2835ALIAS (no_match_aspath,
2836 no_match_aspath_val_cmd,
2837 "no match as-path WORD",
2838 NO_STR
2839 MATCH_STR
2840 "Match BGP AS path list\n"
2841 "AS path access-list name\n")
2842
2843DEFUN (match_origin,
2844 match_origin_cmd,
2845 "match origin (egp|igp|incomplete)",
2846 MATCH_STR
2847 "BGP origin code\n"
2848 "remote EGP\n"
2849 "local IGP\n"
2850 "unknown heritage\n")
2851{
2852 if (strncmp (argv[0], "igp", 2) == 0)
2853 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2854 if (strncmp (argv[0], "egp", 1) == 0)
2855 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2856 if (strncmp (argv[0], "incomplete", 2) == 0)
2857 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2858
2859 return CMD_WARNING;
2860}
2861
2862DEFUN (no_match_origin,
2863 no_match_origin_cmd,
2864 "no match origin",
2865 NO_STR
2866 MATCH_STR
2867 "BGP origin code\n")
2868{
2869 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2870}
2871
2872ALIAS (no_match_origin,
2873 no_match_origin_val_cmd,
2874 "no match origin (egp|igp|incomplete)",
2875 NO_STR
2876 MATCH_STR
2877 "BGP origin code\n"
2878 "remote EGP\n"
2879 "local IGP\n"
2880 "unknown heritage\n")
2881
2882DEFUN (set_ip_nexthop,
2883 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002884 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002885 SET_STR
2886 IP_STR
2887 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002888 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002889{
2890 union sockunion su;
2891 int ret;
2892
2893 ret = str2sockunion (argv[0], &su);
2894 if (ret < 0)
2895 {
2896 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2897 return CMD_WARNING;
2898 }
2899
2900 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2901}
2902
paulaf5cd0a2003-11-02 07:24:40 +00002903DEFUN (set_ip_nexthop_peer,
2904 set_ip_nexthop_peer_cmd,
2905 "set ip next-hop peer-address",
2906 SET_STR
2907 IP_STR
2908 "Next hop address\n"
2909 "Use peer address (for BGP only)\n")
2910{
2911 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2912}
2913
paul94f2b392005-06-28 12:44:16 +00002914DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002915 no_set_ip_nexthop_peer_cmd,
2916 "no set ip next-hop peer-address",
2917 NO_STR
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_delete (vty, vty->index, "ip next-hop", NULL);
2924}
2925
2926
paul718e3742002-12-13 20:15:29 +00002927DEFUN (no_set_ip_nexthop,
2928 no_set_ip_nexthop_cmd,
2929 "no set ip next-hop",
2930 NO_STR
2931 SET_STR
paul718e3742002-12-13 20:15:29 +00002932 "Next hop address\n")
2933{
paulaf5cd0a2003-11-02 07:24:40 +00002934 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002935 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2936
2937 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2938}
2939
2940ALIAS (no_set_ip_nexthop,
2941 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002942 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002943 NO_STR
2944 SET_STR
2945 IP_STR
2946 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002947 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002948
2949DEFUN (set_metric,
2950 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002951 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002952 SET_STR
2953 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002954 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002955{
2956 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2957}
2958
paul73ffb252003-04-19 15:49:49 +00002959ALIAS (set_metric,
2960 set_metric_addsub_cmd,
2961 "set metric <+/-metric>",
2962 SET_STR
2963 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002964 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002965
paul718e3742002-12-13 20:15:29 +00002966DEFUN (no_set_metric,
2967 no_set_metric_cmd,
2968 "no set metric",
2969 NO_STR
2970 SET_STR
2971 "Metric value for destination routing protocol\n")
2972{
2973 if (argc == 0)
2974 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2975
2976 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2977}
2978
2979ALIAS (no_set_metric,
2980 no_set_metric_val_cmd,
2981 "no set metric <0-4294967295>",
2982 NO_STR
2983 SET_STR
2984 "Metric value for destination routing protocol\n"
2985 "Metric value\n")
2986
2987DEFUN (set_local_pref,
2988 set_local_pref_cmd,
2989 "set local-preference <0-4294967295>",
2990 SET_STR
2991 "BGP local preference path attribute\n"
2992 "Preference value\n")
2993{
2994 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2995}
2996
2997DEFUN (no_set_local_pref,
2998 no_set_local_pref_cmd,
2999 "no set local-preference",
3000 NO_STR
3001 SET_STR
3002 "BGP local preference path attribute\n")
3003{
3004 if (argc == 0)
3005 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3006
3007 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3008}
3009
3010ALIAS (no_set_local_pref,
3011 no_set_local_pref_val_cmd,
3012 "no set local-preference <0-4294967295>",
3013 NO_STR
3014 SET_STR
3015 "BGP local preference path attribute\n"
3016 "Preference value\n")
3017
3018DEFUN (set_weight,
3019 set_weight_cmd,
3020 "set weight <0-4294967295>",
3021 SET_STR
3022 "BGP weight for routing table\n"
3023 "Weight value\n")
3024{
3025 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3026}
3027
3028DEFUN (no_set_weight,
3029 no_set_weight_cmd,
3030 "no set weight",
3031 NO_STR
3032 SET_STR
3033 "BGP weight for routing table\n")
3034{
3035 if (argc == 0)
3036 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3037
3038 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3039}
3040
3041ALIAS (no_set_weight,
3042 no_set_weight_val_cmd,
3043 "no set weight <0-4294967295>",
3044 NO_STR
3045 SET_STR
3046 "BGP weight for routing table\n"
3047 "Weight value\n")
3048
3049DEFUN (set_aspath_prepend,
3050 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003051 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003052 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003053 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003054 "Prepend to the as-path\n"
3055 "AS number\n")
3056{
3057 int ret;
3058 char *str;
3059
3060 str = argv_concat (argv, argc, 0);
3061 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3062 XFREE (MTYPE_TMP, str);
3063
3064 return ret;
3065}
3066
3067DEFUN (no_set_aspath_prepend,
3068 no_set_aspath_prepend_cmd,
3069 "no set as-path prepend",
3070 NO_STR
3071 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003072 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003073 "Prepend to the as-path\n")
3074{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003075 int ret;
3076 char *str;
3077
3078 if (argc == 0)
3079 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3080
3081 str = argv_concat (argv, argc, 0);
3082 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3083 XFREE (MTYPE_TMP, str);
3084 return ret;
paul718e3742002-12-13 20:15:29 +00003085}
3086
3087ALIAS (no_set_aspath_prepend,
3088 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003089 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003090 NO_STR
3091 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003092 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003093 "Prepend to the as-path\n"
3094 "AS number\n")
3095
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003096DEFUN (set_aspath_exclude,
3097 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003098 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003099 SET_STR
3100 "Transform BGP AS-path attribute\n"
3101 "Exclude from the as-path\n"
3102 "AS number\n")
3103{
3104 int ret;
3105 char *str;
3106
3107 str = argv_concat (argv, argc, 0);
3108 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3109 XFREE (MTYPE_TMP, str);
3110 return ret;
3111}
3112
3113DEFUN (no_set_aspath_exclude,
3114 no_set_aspath_exclude_cmd,
3115 "no set as-path exclude",
3116 NO_STR
3117 SET_STR
3118 "Transform BGP AS_PATH attribute\n"
3119 "Exclude from the as-path\n")
3120{
3121 int ret;
3122 char *str;
3123
3124 if (argc == 0)
3125 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3126
3127 str = argv_concat (argv, argc, 0);
3128 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3129 XFREE (MTYPE_TMP, str);
3130 return ret;
3131}
3132
3133ALIAS (no_set_aspath_exclude,
3134 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003135 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003136 NO_STR
3137 SET_STR
3138 "Transform BGP AS_PATH attribute\n"
3139 "Exclude from the as-path\n"
3140 "AS number\n")
3141
paul718e3742002-12-13 20:15:29 +00003142DEFUN (set_community,
3143 set_community_cmd,
3144 "set community .AA:NN",
3145 SET_STR
3146 "BGP community attribute\n"
3147 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3148{
3149 int i;
3150 int first = 0;
3151 int additive = 0;
3152 struct buffer *b;
3153 struct community *com = NULL;
3154 char *str;
3155 char *argstr;
3156 int ret;
3157
3158 b = buffer_new (1024);
3159
3160 for (i = 0; i < argc; i++)
3161 {
3162 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3163 {
3164 additive = 1;
3165 continue;
3166 }
3167
3168 if (first)
3169 buffer_putc (b, ' ');
3170 else
3171 first = 1;
3172
3173 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3174 {
3175 buffer_putstr (b, "internet");
3176 continue;
3177 }
3178 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3179 {
3180 buffer_putstr (b, "local-AS");
3181 continue;
3182 }
3183 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3184 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3185 {
3186 buffer_putstr (b, "no-advertise");
3187 continue;
3188 }
3189 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3190 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3191 {
3192 buffer_putstr (b, "no-export");
3193 continue;
3194 }
3195 buffer_putstr (b, argv[i]);
3196 }
3197 buffer_putc (b, '\0');
3198
3199 /* Fetch result string then compile it to communities attribute. */
3200 str = buffer_getstr (b);
3201 buffer_free (b);
3202
3203 if (str)
3204 {
3205 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003206 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003207 }
3208
3209 /* Can't compile user input into communities attribute. */
3210 if (! com)
3211 {
3212 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3213 return CMD_WARNING;
3214 }
3215
3216 /* Set communites attribute string. */
3217 str = community_str (com);
3218
3219 if (additive)
3220 {
3221 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3222 strcpy (argstr, str);
3223 strcpy (argstr + strlen (str), " additive");
3224 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3225 XFREE (MTYPE_TMP, argstr);
3226 }
3227 else
3228 ret = bgp_route_set_add (vty, vty->index, "community", str);
3229
3230 community_free (com);
3231
3232 return ret;
3233}
3234
3235DEFUN (set_community_none,
3236 set_community_none_cmd,
3237 "set community none",
3238 SET_STR
3239 "BGP community attribute\n"
3240 "No community attribute\n")
3241{
3242 return bgp_route_set_add (vty, vty->index, "community", "none");
3243}
3244
3245DEFUN (no_set_community,
3246 no_set_community_cmd,
3247 "no set community",
3248 NO_STR
3249 SET_STR
3250 "BGP community attribute\n")
3251{
3252 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3253}
3254
3255ALIAS (no_set_community,
3256 no_set_community_val_cmd,
3257 "no set community .AA:NN",
3258 NO_STR
3259 SET_STR
3260 "BGP community attribute\n"
3261 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3262
3263ALIAS (no_set_community,
3264 no_set_community_none_cmd,
3265 "no set community none",
3266 NO_STR
3267 SET_STR
3268 "BGP community attribute\n"
3269 "No community attribute\n")
3270
3271DEFUN (set_community_delete,
3272 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003273 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003274 SET_STR
3275 "set BGP community list (for deletion)\n"
3276 "Community-list number (standard)\n"
3277 "Communitly-list number (expanded)\n"
3278 "Community-list name\n"
3279 "Delete matching communities\n")
3280{
3281 char *str;
3282
3283 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3284 strcpy (str, argv[0]);
3285 strcpy (str + strlen (argv[0]), " delete");
3286
3287 bgp_route_set_add (vty, vty->index, "comm-list", str);
3288
3289 XFREE (MTYPE_TMP, str);
3290 return CMD_SUCCESS;
3291}
3292
3293DEFUN (no_set_community_delete,
3294 no_set_community_delete_cmd,
3295 "no set comm-list",
3296 NO_STR
3297 SET_STR
3298 "set BGP community list (for deletion)\n")
3299{
3300 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3301}
3302
3303ALIAS (no_set_community_delete,
3304 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003305 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003306 NO_STR
3307 SET_STR
3308 "set BGP community list (for deletion)\n"
3309 "Community-list number (standard)\n"
3310 "Communitly-list number (expanded)\n"
3311 "Community-list name\n"
3312 "Delete matching communities\n")
3313
3314DEFUN (set_ecommunity_rt,
3315 set_ecommunity_rt_cmd,
3316 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3317 SET_STR
3318 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003319 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003320 "VPN extended community\n")
3321{
3322 int ret;
3323 char *str;
3324
3325 str = argv_concat (argv, argc, 0);
3326 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3327 XFREE (MTYPE_TMP, str);
3328
3329 return ret;
3330}
3331
3332DEFUN (no_set_ecommunity_rt,
3333 no_set_ecommunity_rt_cmd,
3334 "no set extcommunity rt",
3335 NO_STR
3336 SET_STR
3337 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003338 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003339{
3340 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3341}
3342
3343ALIAS (no_set_ecommunity_rt,
3344 no_set_ecommunity_rt_val_cmd,
3345 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3346 NO_STR
3347 SET_STR
3348 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003349 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003350 "VPN extended community\n")
3351
3352DEFUN (set_ecommunity_soo,
3353 set_ecommunity_soo_cmd,
3354 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3355 SET_STR
3356 "BGP extended community attribute\n"
3357 "Site-of-Origin extended community\n"
3358 "VPN extended community\n")
3359{
3360 int ret;
3361 char *str;
3362
3363 str = argv_concat (argv, argc, 0);
3364 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3365 XFREE (MTYPE_TMP, str);
3366 return ret;
3367}
3368
3369DEFUN (no_set_ecommunity_soo,
3370 no_set_ecommunity_soo_cmd,
3371 "no set extcommunity soo",
3372 NO_STR
3373 SET_STR
3374 "BGP extended community attribute\n"
3375 "Site-of-Origin extended community\n")
3376{
3377 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3378}
3379
3380ALIAS (no_set_ecommunity_soo,
3381 no_set_ecommunity_soo_val_cmd,
3382 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3383 NO_STR
3384 SET_STR
3385 "BGP extended community attribute\n"
3386 "Site-of-Origin extended community\n"
3387 "VPN extended community\n")
3388
3389DEFUN (set_origin,
3390 set_origin_cmd,
3391 "set origin (egp|igp|incomplete)",
3392 SET_STR
3393 "BGP origin code\n"
3394 "remote EGP\n"
3395 "local IGP\n"
3396 "unknown heritage\n")
3397{
3398 if (strncmp (argv[0], "igp", 2) == 0)
3399 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3400 if (strncmp (argv[0], "egp", 1) == 0)
3401 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3402 if (strncmp (argv[0], "incomplete", 2) == 0)
3403 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3404
3405 return CMD_WARNING;
3406}
3407
3408DEFUN (no_set_origin,
3409 no_set_origin_cmd,
3410 "no set origin",
3411 NO_STR
3412 SET_STR
3413 "BGP origin code\n")
3414{
3415 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3416}
3417
3418ALIAS (no_set_origin,
3419 no_set_origin_val_cmd,
3420 "no set origin (egp|igp|incomplete)",
3421 NO_STR
3422 SET_STR
3423 "BGP origin code\n"
3424 "remote EGP\n"
3425 "local IGP\n"
3426 "unknown heritage\n")
3427
3428DEFUN (set_atomic_aggregate,
3429 set_atomic_aggregate_cmd,
3430 "set atomic-aggregate",
3431 SET_STR
3432 "BGP atomic aggregate attribute\n" )
3433{
3434 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3435}
3436
3437DEFUN (no_set_atomic_aggregate,
3438 no_set_atomic_aggregate_cmd,
3439 "no set atomic-aggregate",
3440 NO_STR
3441 SET_STR
3442 "BGP atomic aggregate attribute\n" )
3443{
3444 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3445}
3446
3447DEFUN (set_aggregator_as,
3448 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003449 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003450 SET_STR
3451 "BGP aggregator attribute\n"
3452 "AS number of aggregator\n"
3453 "AS number\n"
3454 "IP address of aggregator\n")
3455{
3456 int ret;
3457 as_t as;
3458 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003459 char *argstr;
3460
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003461 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003462
paul718e3742002-12-13 20:15:29 +00003463 ret = inet_aton (argv[1], &address);
3464 if (ret == 0)
3465 {
3466 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3467 return CMD_WARNING;
3468 }
3469
3470 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3471 strlen (argv[0]) + strlen (argv[1]) + 2);
3472
3473 sprintf (argstr, "%s %s", argv[0], argv[1]);
3474
3475 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3476
3477 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3478
3479 return ret;
3480}
3481
3482DEFUN (no_set_aggregator_as,
3483 no_set_aggregator_as_cmd,
3484 "no set aggregator as",
3485 NO_STR
3486 SET_STR
3487 "BGP aggregator attribute\n"
3488 "AS number of aggregator\n")
3489{
3490 int ret;
3491 as_t as;
3492 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003493 char *argstr;
3494
3495 if (argv == 0)
3496 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3497
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003498 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003499
3500 ret = inet_aton (argv[1], &address);
3501 if (ret == 0)
3502 {
3503 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3504 return CMD_WARNING;
3505 }
3506
3507 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3508 strlen (argv[0]) + strlen (argv[1]) + 2);
3509
3510 sprintf (argstr, "%s %s", argv[0], argv[1]);
3511
3512 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3513
3514 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3515
3516 return ret;
3517}
3518
3519ALIAS (no_set_aggregator_as,
3520 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003521 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003522 NO_STR
3523 SET_STR
3524 "BGP aggregator attribute\n"
3525 "AS number of aggregator\n"
3526 "AS number\n"
3527 "IP address of aggregator\n")
3528
David Lamparter6b0655a2014-06-04 06:53:35 +02003529
paul718e3742002-12-13 20:15:29 +00003530#ifdef HAVE_IPV6
3531DEFUN (match_ipv6_address,
3532 match_ipv6_address_cmd,
3533 "match ipv6 address WORD",
3534 MATCH_STR
3535 IPV6_STR
3536 "Match IPv6 address of route\n"
3537 "IPv6 access-list name\n")
3538{
3539 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3540}
3541
3542DEFUN (no_match_ipv6_address,
3543 no_match_ipv6_address_cmd,
3544 "no match ipv6 address WORD",
3545 NO_STR
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_delete (vty, vty->index, "ipv6 address", argv[0]);
3552}
3553
3554DEFUN (match_ipv6_next_hop,
3555 match_ipv6_next_hop_cmd,
3556 "match ipv6 next-hop X:X::X:X",
3557 MATCH_STR
3558 IPV6_STR
3559 "Match IPv6 next-hop address of route\n"
3560 "IPv6 address of next hop\n")
3561{
3562 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3563}
3564
3565DEFUN (no_match_ipv6_next_hop,
3566 no_match_ipv6_next_hop_cmd,
3567 "no match ipv6 next-hop X:X::X:X",
3568 NO_STR
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_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3575}
3576
3577DEFUN (match_ipv6_address_prefix_list,
3578 match_ipv6_address_prefix_list_cmd,
3579 "match ipv6 address prefix-list WORD",
3580 MATCH_STR
3581 IPV6_STR
3582 "Match address of route\n"
3583 "Match entries of prefix-lists\n"
3584 "IP prefix-list name\n")
3585{
3586 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3587}
3588
3589DEFUN (no_match_ipv6_address_prefix_list,
3590 no_match_ipv6_address_prefix_list_cmd,
3591 "no match ipv6 address prefix-list WORD",
3592 NO_STR
3593 MATCH_STR
3594 IPV6_STR
3595 "Match address of route\n"
3596 "Match entries of prefix-lists\n"
3597 "IP prefix-list name\n")
3598{
3599 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3600}
3601
3602DEFUN (set_ipv6_nexthop_global,
3603 set_ipv6_nexthop_global_cmd,
3604 "set ipv6 next-hop global X:X::X:X",
3605 SET_STR
3606 IPV6_STR
3607 "IPv6 next-hop address\n"
3608 "IPv6 global address\n"
3609 "IPv6 address of next hop\n")
3610{
3611 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3612}
3613
3614DEFUN (no_set_ipv6_nexthop_global,
3615 no_set_ipv6_nexthop_global_cmd,
3616 "no set ipv6 next-hop global",
3617 NO_STR
3618 SET_STR
3619 IPV6_STR
3620 "IPv6 next-hop address\n"
3621 "IPv6 global address\n")
3622{
3623 if (argc == 0)
3624 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3625
3626 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3627}
3628
3629ALIAS (no_set_ipv6_nexthop_global,
3630 no_set_ipv6_nexthop_global_val_cmd,
3631 "no set ipv6 next-hop global X:X::X:X",
3632 NO_STR
3633 SET_STR
3634 IPV6_STR
3635 "IPv6 next-hop address\n"
3636 "IPv6 global address\n"
3637 "IPv6 address of next hop\n")
3638
3639DEFUN (set_ipv6_nexthop_local,
3640 set_ipv6_nexthop_local_cmd,
3641 "set ipv6 next-hop local X:X::X:X",
3642 SET_STR
3643 IPV6_STR
3644 "IPv6 next-hop address\n"
3645 "IPv6 local address\n"
3646 "IPv6 address of next hop\n")
3647{
3648 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3649}
3650
3651DEFUN (no_set_ipv6_nexthop_local,
3652 no_set_ipv6_nexthop_local_cmd,
3653 "no set ipv6 next-hop local",
3654 NO_STR
3655 SET_STR
3656 IPV6_STR
3657 "IPv6 next-hop address\n"
3658 "IPv6 local address\n")
3659{
3660 if (argc == 0)
3661 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3662
3663 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3664}
3665
3666ALIAS (no_set_ipv6_nexthop_local,
3667 no_set_ipv6_nexthop_local_val_cmd,
3668 "no set ipv6 next-hop local X:X::X:X",
3669 NO_STR
3670 SET_STR
3671 IPV6_STR
3672 "IPv6 next-hop address\n"
3673 "IPv6 local address\n"
3674 "IPv6 address of next hop\n")
3675#endif /* HAVE_IPV6 */
3676
3677DEFUN (set_vpnv4_nexthop,
3678 set_vpnv4_nexthop_cmd,
3679 "set vpnv4 next-hop A.B.C.D",
3680 SET_STR
3681 "VPNv4 information\n"
3682 "VPNv4 next-hop address\n"
3683 "IP address of next hop\n")
3684{
3685 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3686}
3687
3688DEFUN (no_set_vpnv4_nexthop,
3689 no_set_vpnv4_nexthop_cmd,
3690 "no set vpnv4 next-hop",
3691 NO_STR
3692 SET_STR
3693 "VPNv4 information\n"
3694 "VPNv4 next-hop address\n")
3695{
3696 if (argc == 0)
3697 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3698
3699 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3700}
3701
3702ALIAS (no_set_vpnv4_nexthop,
3703 no_set_vpnv4_nexthop_val_cmd,
3704 "no set vpnv4 next-hop A.B.C.D",
3705 NO_STR
3706 SET_STR
3707 "VPNv4 information\n"
3708 "VPNv4 next-hop address\n"
3709 "IP address of next hop\n")
3710
3711DEFUN (set_originator_id,
3712 set_originator_id_cmd,
3713 "set originator-id A.B.C.D",
3714 SET_STR
3715 "BGP originator ID attribute\n"
3716 "IP address of originator\n")
3717{
3718 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3719}
3720
3721DEFUN (no_set_originator_id,
3722 no_set_originator_id_cmd,
3723 "no set originator-id",
3724 NO_STR
3725 SET_STR
3726 "BGP originator ID attribute\n")
3727{
3728 if (argc == 0)
3729 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3730
3731 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3732}
3733
3734ALIAS (no_set_originator_id,
3735 no_set_originator_id_val_cmd,
3736 "no set originator-id A.B.C.D",
3737 NO_STR
3738 SET_STR
3739 "BGP originator ID attribute\n"
3740 "IP address of originator\n")
3741
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003742DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003743 set_pathlimit_ttl_cmd,
3744 "set pathlimit ttl <1-255>",
3745 SET_STR
3746 "BGP AS-Pathlimit attribute\n"
3747 "Set AS-Path Hop-count TTL\n")
3748{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003749 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003750}
3751
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003752DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003753 no_set_pathlimit_ttl_cmd,
3754 "no set pathlimit ttl",
3755 NO_STR
3756 SET_STR
3757 "BGP AS-Pathlimit attribute\n"
3758 "Set AS-Path Hop-count TTL\n")
3759{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003760 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003761}
3762
3763ALIAS (no_set_pathlimit_ttl,
3764 no_set_pathlimit_ttl_val_cmd,
3765 "no set pathlimit ttl <1-255>",
3766 NO_STR
3767 MATCH_STR
3768 "BGP AS-Pathlimit attribute\n"
3769 "Set AS-Path Hop-count TTL\n")
3770
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003771DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003772 match_pathlimit_as_cmd,
3773 "match pathlimit as <1-65535>",
3774 MATCH_STR
3775 "BGP AS-Pathlimit attribute\n"
3776 "Match Pathlimit AS number\n")
3777{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003778 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003779}
3780
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003781DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003782 no_match_pathlimit_as_cmd,
3783 "no match pathlimit as",
3784 NO_STR
3785 MATCH_STR
3786 "BGP AS-Pathlimit attribute\n"
3787 "Match Pathlimit AS number\n")
3788{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003789 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003790}
3791
3792ALIAS (no_match_pathlimit_as,
3793 no_match_pathlimit_as_val_cmd,
3794 "no match pathlimit as <1-65535>",
3795 NO_STR
3796 MATCH_STR
3797 "BGP AS-Pathlimit attribute\n"
3798 "Match Pathlimit ASN\n")
3799
David Lamparter6b0655a2014-06-04 06:53:35 +02003800
paul718e3742002-12-13 20:15:29 +00003801/* Initialization of route map. */
3802void
paul94f2b392005-06-28 12:44:16 +00003803bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003804{
3805 route_map_init ();
3806 route_map_init_vty ();
3807 route_map_add_hook (bgp_route_map_update);
3808 route_map_delete_hook (bgp_route_map_update);
3809
paulfee0f4c2004-09-13 05:12:46 +00003810 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003811 route_map_install_match (&route_match_ip_address_cmd);
3812 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003813 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003814 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3815 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003816 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003817 route_map_install_match (&route_match_aspath_cmd);
3818 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003819 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003820 route_map_install_match (&route_match_metric_cmd);
3821 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003822 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003823
3824 route_map_install_set (&route_set_ip_nexthop_cmd);
3825 route_map_install_set (&route_set_local_pref_cmd);
3826 route_map_install_set (&route_set_weight_cmd);
3827 route_map_install_set (&route_set_metric_cmd);
3828 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003829 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003830 route_map_install_set (&route_set_origin_cmd);
3831 route_map_install_set (&route_set_atomic_aggregate_cmd);
3832 route_map_install_set (&route_set_aggregator_as_cmd);
3833 route_map_install_set (&route_set_community_cmd);
3834 route_map_install_set (&route_set_community_delete_cmd);
3835 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3836 route_map_install_set (&route_set_originator_id_cmd);
3837 route_map_install_set (&route_set_ecommunity_rt_cmd);
3838 route_map_install_set (&route_set_ecommunity_soo_cmd);
3839
paulfee0f4c2004-09-13 05:12:46 +00003840 install_element (RMAP_NODE, &match_peer_cmd);
3841 install_element (RMAP_NODE, &match_peer_local_cmd);
3842 install_element (RMAP_NODE, &no_match_peer_cmd);
3843 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3844 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003845 install_element (RMAP_NODE, &match_ip_address_cmd);
3846 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3847 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3848 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3849 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3850 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003851 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3852 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3853 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003854 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3855 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3856 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3857 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3858 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3859 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003860 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3861 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3862 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003863
3864 install_element (RMAP_NODE, &match_aspath_cmd);
3865 install_element (RMAP_NODE, &no_match_aspath_cmd);
3866 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3867 install_element (RMAP_NODE, &match_metric_cmd);
3868 install_element (RMAP_NODE, &no_match_metric_cmd);
3869 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3870 install_element (RMAP_NODE, &match_community_cmd);
3871 install_element (RMAP_NODE, &match_community_exact_cmd);
3872 install_element (RMAP_NODE, &no_match_community_cmd);
3873 install_element (RMAP_NODE, &no_match_community_val_cmd);
3874 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003875 install_element (RMAP_NODE, &match_ecommunity_cmd);
3876 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3877 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003878 install_element (RMAP_NODE, &match_origin_cmd);
3879 install_element (RMAP_NODE, &no_match_origin_cmd);
3880 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003881 install_element (RMAP_NODE, &match_probability_cmd);
3882 install_element (RMAP_NODE, &no_match_probability_cmd);
3883 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003884
3885 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003886 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003887 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3888 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3889 install_element (RMAP_NODE, &set_local_pref_cmd);
3890 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3891 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3892 install_element (RMAP_NODE, &set_weight_cmd);
3893 install_element (RMAP_NODE, &no_set_weight_cmd);
3894 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3895 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003896 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003897 install_element (RMAP_NODE, &no_set_metric_cmd);
3898 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3899 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003900 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003901 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3902 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003903 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3904 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003905 install_element (RMAP_NODE, &set_origin_cmd);
3906 install_element (RMAP_NODE, &no_set_origin_cmd);
3907 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3908 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3909 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3910 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3911 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3912 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3913 install_element (RMAP_NODE, &set_community_cmd);
3914 install_element (RMAP_NODE, &set_community_none_cmd);
3915 install_element (RMAP_NODE, &no_set_community_cmd);
3916 install_element (RMAP_NODE, &no_set_community_val_cmd);
3917 install_element (RMAP_NODE, &no_set_community_none_cmd);
3918 install_element (RMAP_NODE, &set_community_delete_cmd);
3919 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3920 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3921 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3922 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3923 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3924 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3925 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3926 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3927 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3928 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3929 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3930 install_element (RMAP_NODE, &set_originator_id_cmd);
3931 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3932 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3933
3934#ifdef HAVE_IPV6
3935 route_map_install_match (&route_match_ipv6_address_cmd);
3936 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3937 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3938 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3939 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003940
paul718e3742002-12-13 20:15:29 +00003941 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3942 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3943 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3944 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3945 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3946 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3947 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3948 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3949 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3950 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3951 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3952 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3953#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003954
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003955 /* AS-Pathlimit: functionality removed, commands kept for
3956 * compatibility.
3957 */
Paul Jakma41367172007-08-06 15:24:51 +00003958 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3959 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3960 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3961 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3962 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3963 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003964}