blob: f2204003299874ba56155e1d94045b3f01334849 [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*/
103
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};
243
244/* `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};
295
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};
353
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};
393
394/* `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};
440
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};
493
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};
558
559/* `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};
paul718e3742002-12-13 20:15:29 +0000606
607/* `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};
690
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};
739
paul718e3742002-12-13 20:15:29 +0000740/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
741 and `address-family vpnv4'. */
742
743/* `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};
967
968/* `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};
1034
1035/* `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};
1103
1104/* `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};
1203
1204/* `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};
1259
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};
1317
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;
1350 return RMAP_OKAY;
1351 }
1352
1353 /* "additive" case. */
1354 if (rcs->additive && old)
1355 {
1356 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001357
1358 /* HACK: if the old community is not intern'd,
1359 * we should free it here, or all reference to it may be lost.
1360 * Really need to cleanup attribute caching sometime.
1361 */
1362 if (old->refcnt == 0)
1363 community_free (old);
paul718e3742002-12-13 20:15:29 +00001364 new = community_uniq_sort (merge);
1365 community_free (merge);
1366 }
1367 else
1368 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001369
1370 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001371 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001372
paul718e3742002-12-13 20:15:29 +00001373 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1374 }
1375
1376 return RMAP_OKAY;
1377}
1378
1379/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001380static void *
paulfd79ac92004-10-13 05:06:08 +00001381route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001382{
1383 struct rmap_com_set *rcs;
1384 struct community *com = NULL;
1385 char *sp;
1386 int additive = 0;
1387 int none = 0;
1388
1389 if (strcmp (arg, "none") == 0)
1390 none = 1;
1391 else
1392 {
1393 sp = strstr (arg, "additive");
1394
1395 if (sp && sp > arg)
1396 {
1397 /* "additive" keyworkd is included. */
1398 additive = 1;
1399 *(sp - 1) = '\0';
1400 }
1401
1402 com = community_str2com (arg);
1403
1404 if (additive)
1405 *(sp - 1) = ' ';
1406
1407 if (! com)
1408 return NULL;
1409 }
1410
Stephen Hemminger393deb92008-08-18 14:13:29 -07001411 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001412 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001413 rcs->additive = additive;
1414 rcs->none = none;
1415
1416 return rcs;
1417}
1418
1419/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001420static void
paul718e3742002-12-13 20:15:29 +00001421route_set_community_free (void *rule)
1422{
1423 struct rmap_com_set *rcs = rule;
1424
1425 if (rcs->com)
1426 community_free (rcs->com);
1427 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1428}
1429
1430/* Set community rule structure. */
1431struct route_map_rule_cmd route_set_community_cmd =
1432{
1433 "community",
1434 route_set_community,
1435 route_set_community_compile,
1436 route_set_community_free,
1437};
1438
hassofee6e4e2005-02-02 16:29:31 +00001439/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001440
1441/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001442static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001443route_set_community_delete (void *rule, struct prefix *prefix,
1444 route_map_object_t type, void *object)
1445{
1446 struct community_list *list;
1447 struct community *merge;
1448 struct community *new;
1449 struct community *old;
1450 struct bgp_info *binfo;
1451
1452 if (type == RMAP_BGP)
1453 {
1454 if (! rule)
1455 return RMAP_OKAY;
1456
1457 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001458 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001459 old = binfo->attr->community;
1460
1461 if (list && old)
1462 {
1463 merge = community_list_match_delete (community_dup (old), list);
1464 new = community_uniq_sort (merge);
1465 community_free (merge);
1466
Michael Lambert604a9b42010-09-13 11:48:11 -04001467 /* HACK: if the old community is not intern'd,
1468 * we should free it here, or all reference to it may be lost.
1469 * Really need to cleanup attribute caching sometime.
1470 */
1471 if (old->refcnt == 0)
1472 community_free (old);
1473
paul718e3742002-12-13 20:15:29 +00001474 if (new->size == 0)
1475 {
1476 binfo->attr->community = NULL;
1477 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1478 community_free (new);
1479 }
1480 else
1481 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001482 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001483 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1484 }
1485 }
1486 }
1487
1488 return RMAP_OKAY;
1489}
1490
1491/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001492static void *
paulfd79ac92004-10-13 05:06:08 +00001493route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001494{
1495 char *p;
1496 char *str;
1497 int len;
1498
1499 p = strchr (arg, ' ');
1500 if (p)
1501 {
1502 len = p - arg;
1503 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1504 memcpy (str, arg, len);
1505 }
1506 else
1507 str = NULL;
1508
1509 return str;
1510}
1511
1512/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001513static void
paul718e3742002-12-13 20:15:29 +00001514route_set_community_delete_free (void *rule)
1515{
1516 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1517}
1518
1519/* Set community rule structure. */
1520struct route_map_rule_cmd route_set_community_delete_cmd =
1521{
1522 "comm-list",
1523 route_set_community_delete,
1524 route_set_community_delete_compile,
1525 route_set_community_delete_free,
1526};
1527
1528/* `set extcommunity rt COMMUNITY' */
1529
1530/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001531static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001532route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1533 route_map_object_t type, void *object)
1534{
1535 struct ecommunity *ecom;
1536 struct ecommunity *new_ecom;
1537 struct ecommunity *old_ecom;
1538 struct bgp_info *bgp_info;
1539
1540 if (type == RMAP_BGP)
1541 {
1542 ecom = rule;
1543 bgp_info = object;
1544
1545 if (! ecom)
1546 return RMAP_OKAY;
1547
1548 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001549 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001550
1551 if (old_ecom)
1552 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1553 else
1554 new_ecom = ecommunity_dup (ecom);
1555
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001556 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
paul718e3742002-12-13 20:15:29 +00001557
hasso70601e02005-05-27 03:26:57 +00001558 if (old_ecom)
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001559 ecommunity_unintern (&old_ecom);
hasso70601e02005-05-27 03:26:57 +00001560
paul718e3742002-12-13 20:15:29 +00001561 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1562 }
1563 return RMAP_OKAY;
1564}
1565
1566/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001567static void *
paulfd79ac92004-10-13 05:06:08 +00001568route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001569{
1570 struct ecommunity *ecom;
1571
1572 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1573 if (! ecom)
1574 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001575 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001576}
1577
1578/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001579static void
paul718e3742002-12-13 20:15:29 +00001580route_set_ecommunity_rt_free (void *rule)
1581{
1582 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001583 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001584}
1585
1586/* Set community rule structure. */
1587struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1588{
1589 "extcommunity rt",
1590 route_set_ecommunity_rt,
1591 route_set_ecommunity_rt_compile,
1592 route_set_ecommunity_rt_free,
1593};
1594
1595/* `set extcommunity soo COMMUNITY' */
1596
1597/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001598static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001599route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1600 route_map_object_t type, void *object)
1601{
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001602 struct ecommunity *ecom, *old_ecom, *new_ecom;
paul718e3742002-12-13 20:15:29 +00001603 struct bgp_info *bgp_info;
1604
1605 if (type == RMAP_BGP)
1606 {
1607 ecom = rule;
1608 bgp_info = object;
1609
1610 if (! ecom)
1611 return RMAP_OKAY;
1612
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001613 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1614
1615 if (old_ecom)
1616 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1617 else
1618 new_ecom = ecommunity_dup (ecom);
1619
1620 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1621
1622 if (old_ecom)
1623 ecommunity_unintern (&old_ecom);
1624
paul718e3742002-12-13 20:15:29 +00001625 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
paul718e3742002-12-13 20:15:29 +00001626 }
1627 return RMAP_OKAY;
1628}
1629
1630/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001631static void *
paulfd79ac92004-10-13 05:06:08 +00001632route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001633{
1634 struct ecommunity *ecom;
1635
1636 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1637 if (! ecom)
1638 return NULL;
1639
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001640 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001641}
1642
1643/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001644static void
paul718e3742002-12-13 20:15:29 +00001645route_set_ecommunity_soo_free (void *rule)
1646{
1647 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001648 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001649}
1650
1651/* Set community rule structure. */
1652struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1653{
1654 "extcommunity soo",
1655 route_set_ecommunity_soo,
1656 route_set_ecommunity_soo_compile,
1657 route_set_ecommunity_soo_free,
1658};
1659
1660/* `set origin ORIGIN' */
1661
1662/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001663static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001664route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1665{
1666 u_char *origin;
1667 struct bgp_info *bgp_info;
1668
1669 if (type == RMAP_BGP)
1670 {
1671 origin = rule;
1672 bgp_info = object;
1673
1674 bgp_info->attr->origin = *origin;
1675 }
1676
1677 return RMAP_OKAY;
1678}
1679
1680/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001681static void *
paulfd79ac92004-10-13 05:06:08 +00001682route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001683{
1684 u_char *origin;
1685
1686 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1687
1688 if (strcmp (arg, "igp") == 0)
1689 *origin = 0;
1690 else if (strcmp (arg, "egp") == 0)
1691 *origin = 1;
1692 else
1693 *origin = 2;
1694
1695 return origin;
1696}
1697
1698/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001699static void
paul718e3742002-12-13 20:15:29 +00001700route_set_origin_free (void *rule)
1701{
1702 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1703}
1704
1705/* Set metric rule structure. */
1706struct route_map_rule_cmd route_set_origin_cmd =
1707{
1708 "origin",
1709 route_set_origin,
1710 route_set_origin_compile,
1711 route_set_origin_free,
1712};
1713
1714/* `set atomic-aggregate' */
1715
1716/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001717static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001718route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1719 route_map_object_t type, void *object)
1720{
1721 struct bgp_info *bgp_info;
1722
1723 if (type == RMAP_BGP)
1724 {
1725 bgp_info = object;
1726 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1727 }
1728
1729 return RMAP_OKAY;
1730}
1731
1732/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001733static void *
paulfd79ac92004-10-13 05:06:08 +00001734route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001735{
1736 return (void *)1;
1737}
1738
1739/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001740static void
paul718e3742002-12-13 20:15:29 +00001741route_set_atomic_aggregate_free (void *rule)
1742{
1743 return;
1744}
1745
1746/* Set atomic aggregate rule structure. */
1747struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1748{
1749 "atomic-aggregate",
1750 route_set_atomic_aggregate,
1751 route_set_atomic_aggregate_compile,
1752 route_set_atomic_aggregate_free,
1753};
1754
1755/* `set aggregator as AS A.B.C.D' */
1756struct aggregator
1757{
1758 as_t as;
1759 struct in_addr address;
1760};
1761
paul94f2b392005-06-28 12:44:16 +00001762static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001763route_set_aggregator_as (void *rule, struct prefix *prefix,
1764 route_map_object_t type, void *object)
1765{
1766 struct bgp_info *bgp_info;
1767 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001768 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001769
1770 if (type == RMAP_BGP)
1771 {
1772 bgp_info = object;
1773 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001774 ae = bgp_attr_extra_get (bgp_info->attr);
1775
1776 ae->aggregator_as = aggregator->as;
1777 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001778 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1779 }
1780
1781 return RMAP_OKAY;
1782}
1783
paul94f2b392005-06-28 12:44:16 +00001784static void *
paulfd79ac92004-10-13 05:06:08 +00001785route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001786{
1787 struct aggregator *aggregator;
1788 char as[10];
1789 char address[20];
1790
Stephen Hemminger393deb92008-08-18 14:13:29 -07001791 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001792 sscanf (arg, "%s %s", as, address);
1793
1794 aggregator->as = strtoul (as, NULL, 10);
1795 inet_aton (address, &aggregator->address);
1796
1797 return aggregator;
1798}
1799
paul94f2b392005-06-28 12:44:16 +00001800static void
paul718e3742002-12-13 20:15:29 +00001801route_set_aggregator_as_free (void *rule)
1802{
1803 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1804}
1805
1806struct route_map_rule_cmd route_set_aggregator_as_cmd =
1807{
1808 "aggregator as",
1809 route_set_aggregator_as,
1810 route_set_aggregator_as_compile,
1811 route_set_aggregator_as_free,
1812};
1813
1814#ifdef HAVE_IPV6
1815/* `match ipv6 address IP_ACCESS_LIST' */
1816
paul94f2b392005-06-28 12:44:16 +00001817static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001818route_match_ipv6_address (void *rule, struct prefix *prefix,
1819 route_map_object_t type, void *object)
1820{
1821 struct access_list *alist;
1822
1823 if (type == RMAP_BGP)
1824 {
1825 alist = access_list_lookup (AFI_IP6, (char *) rule);
1826 if (alist == NULL)
1827 return RMAP_NOMATCH;
1828
1829 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1830 RMAP_NOMATCH : RMAP_MATCH);
1831 }
1832 return RMAP_NOMATCH;
1833}
1834
paul94f2b392005-06-28 12:44:16 +00001835static void *
paulfd79ac92004-10-13 05:06:08 +00001836route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001837{
1838 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1839}
1840
paul94f2b392005-06-28 12:44:16 +00001841static void
paul718e3742002-12-13 20:15:29 +00001842route_match_ipv6_address_free (void *rule)
1843{
1844 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1845}
1846
1847/* Route map commands for ip address matching. */
1848struct route_map_rule_cmd route_match_ipv6_address_cmd =
1849{
1850 "ipv6 address",
1851 route_match_ipv6_address,
1852 route_match_ipv6_address_compile,
1853 route_match_ipv6_address_free
1854};
1855
1856/* `match ipv6 next-hop IP_ADDRESS' */
1857
paul94f2b392005-06-28 12:44:16 +00001858static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001859route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1860 route_map_object_t type, void *object)
1861{
1862 struct in6_addr *addr;
1863 struct bgp_info *bgp_info;
1864
1865 if (type == RMAP_BGP)
1866 {
1867 addr = rule;
1868 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001869
1870 if (!bgp_info->attr->extra)
1871 return RMAP_NOMATCH;
1872
1873 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001874 return RMAP_MATCH;
1875
Paul Jakmafb982c22007-05-04 20:15:47 +00001876 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1877 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001878 return RMAP_MATCH;
1879
1880 return RMAP_NOMATCH;
1881 }
1882
1883 return RMAP_NOMATCH;
1884}
1885
paul94f2b392005-06-28 12:44:16 +00001886static void *
paulfd79ac92004-10-13 05:06:08 +00001887route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001888{
1889 struct in6_addr *address;
1890 int ret;
1891
1892 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1893
1894 ret = inet_pton (AF_INET6, arg, address);
1895 if (!ret)
1896 {
1897 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1898 return NULL;
1899 }
1900
1901 return address;
1902}
1903
paul94f2b392005-06-28 12:44:16 +00001904static void
paul718e3742002-12-13 20:15:29 +00001905route_match_ipv6_next_hop_free (void *rule)
1906{
1907 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1908}
1909
1910struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1911{
1912 "ipv6 next-hop",
1913 route_match_ipv6_next_hop,
1914 route_match_ipv6_next_hop_compile,
1915 route_match_ipv6_next_hop_free
1916};
1917
1918/* `match ipv6 address prefix-list PREFIX_LIST' */
1919
paul94f2b392005-06-28 12:44:16 +00001920static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001921route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1922 route_map_object_t type, void *object)
1923{
1924 struct prefix_list *plist;
1925
1926 if (type == RMAP_BGP)
1927 {
1928 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1929 if (plist == NULL)
1930 return RMAP_NOMATCH;
1931
1932 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1933 RMAP_NOMATCH : RMAP_MATCH);
1934 }
1935 return RMAP_NOMATCH;
1936}
1937
paul94f2b392005-06-28 12:44:16 +00001938static void *
paulfd79ac92004-10-13 05:06:08 +00001939route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001940{
1941 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1942}
1943
paul94f2b392005-06-28 12:44:16 +00001944static void
paul718e3742002-12-13 20:15:29 +00001945route_match_ipv6_address_prefix_list_free (void *rule)
1946{
1947 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1948}
1949
1950struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1951{
1952 "ipv6 address prefix-list",
1953 route_match_ipv6_address_prefix_list,
1954 route_match_ipv6_address_prefix_list_compile,
1955 route_match_ipv6_address_prefix_list_free
1956};
1957
1958/* `set ipv6 nexthop global IP_ADDRESS' */
1959
1960/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001961static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001962route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1963 route_map_object_t type, void *object)
1964{
1965 struct in6_addr *address;
1966 struct bgp_info *bgp_info;
1967
1968 if (type == RMAP_BGP)
1969 {
1970 /* Fetch routemap's rule information. */
1971 address = rule;
1972 bgp_info = object;
1973
1974 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001975 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001976
1977 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001978 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1979 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001980 }
1981
1982 return RMAP_OKAY;
1983}
1984
1985/* Route map `ip next-hop' compile function. Given string is converted
1986 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001987static void *
paulfd79ac92004-10-13 05:06:08 +00001988route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001989{
1990 int ret;
1991 struct in6_addr *address;
1992
1993 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1994
1995 ret = inet_pton (AF_INET6, arg, address);
1996
1997 if (ret == 0)
1998 {
1999 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2000 return NULL;
2001 }
2002
2003 return address;
2004}
2005
2006/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002007static void
paul718e3742002-12-13 20:15:29 +00002008route_set_ipv6_nexthop_global_free (void *rule)
2009{
2010 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2011}
2012
2013/* Route map commands for ip nexthop set. */
2014struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2015{
2016 "ipv6 next-hop global",
2017 route_set_ipv6_nexthop_global,
2018 route_set_ipv6_nexthop_global_compile,
2019 route_set_ipv6_nexthop_global_free
2020};
2021
2022/* `set ipv6 nexthop local IP_ADDRESS' */
2023
2024/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002025static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002026route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2027 route_map_object_t type, void *object)
2028{
2029 struct in6_addr *address;
2030 struct bgp_info *bgp_info;
2031
2032 if (type == RMAP_BGP)
2033 {
2034 /* Fetch routemap's rule information. */
2035 address = rule;
2036 bgp_info = object;
2037
2038 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002039 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002040
2041 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002042 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2043 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002044 }
2045
2046 return RMAP_OKAY;
2047}
2048
2049/* Route map `ip nexthop' compile function. Given string is converted
2050 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002051static void *
paulfd79ac92004-10-13 05:06:08 +00002052route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002053{
2054 int ret;
2055 struct in6_addr *address;
2056
2057 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2058
2059 ret = inet_pton (AF_INET6, arg, address);
2060
2061 if (ret == 0)
2062 {
2063 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2064 return NULL;
2065 }
2066
2067 return address;
2068}
2069
2070/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002071static void
paul718e3742002-12-13 20:15:29 +00002072route_set_ipv6_nexthop_local_free (void *rule)
2073{
2074 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2075}
2076
2077/* Route map commands for ip nexthop set. */
2078struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2079{
2080 "ipv6 next-hop local",
2081 route_set_ipv6_nexthop_local,
2082 route_set_ipv6_nexthop_local_compile,
2083 route_set_ipv6_nexthop_local_free
2084};
2085#endif /* HAVE_IPV6 */
2086
2087/* `set vpnv4 nexthop A.B.C.D' */
2088
paul94f2b392005-06-28 12:44:16 +00002089static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002090route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2091 route_map_object_t type, void *object)
2092{
2093 struct in_addr *address;
2094 struct bgp_info *bgp_info;
2095
2096 if (type == RMAP_BGP)
2097 {
2098 /* Fetch routemap's rule information. */
2099 address = rule;
2100 bgp_info = object;
2101
2102 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002103 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002104 }
2105
2106 return RMAP_OKAY;
2107}
2108
paul94f2b392005-06-28 12:44:16 +00002109static void *
paulfd79ac92004-10-13 05:06:08 +00002110route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002111{
2112 int ret;
2113 struct in_addr *address;
2114
2115 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2116
2117 ret = inet_aton (arg, address);
2118
2119 if (ret == 0)
2120 {
2121 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2122 return NULL;
2123 }
2124
2125 return address;
2126}
2127
paul94f2b392005-06-28 12:44:16 +00002128static void
paul718e3742002-12-13 20:15:29 +00002129route_set_vpnv4_nexthop_free (void *rule)
2130{
2131 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2132}
2133
2134/* Route map commands for ip nexthop set. */
2135struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2136{
2137 "vpnv4 next-hop",
2138 route_set_vpnv4_nexthop,
2139 route_set_vpnv4_nexthop_compile,
2140 route_set_vpnv4_nexthop_free
2141};
2142
2143/* `set originator-id' */
2144
2145/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002146static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002147route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2148{
2149 struct in_addr *address;
2150 struct bgp_info *bgp_info;
2151
2152 if (type == RMAP_BGP)
2153 {
2154 address = rule;
2155 bgp_info = object;
2156
2157 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002158 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002159 }
2160
2161 return RMAP_OKAY;
2162}
2163
2164/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002165static void *
paulfd79ac92004-10-13 05:06:08 +00002166route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002167{
2168 int ret;
2169 struct in_addr *address;
2170
2171 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2172
2173 ret = inet_aton (arg, address);
2174
2175 if (ret == 0)
2176 {
2177 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2178 return NULL;
2179 }
2180
2181 return address;
2182}
2183
2184/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002185static void
paul718e3742002-12-13 20:15:29 +00002186route_set_originator_id_free (void *rule)
2187{
2188 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2189}
2190
2191/* Set metric rule structure. */
2192struct route_map_rule_cmd route_set_originator_id_cmd =
2193{
2194 "originator-id",
2195 route_set_originator_id,
2196 route_set_originator_id_compile,
2197 route_set_originator_id_free,
2198};
2199
2200/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002201static int
paul718e3742002-12-13 20:15:29 +00002202bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002203 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002204{
2205 int ret;
2206
2207 ret = route_map_add_match (index, command, arg);
2208 if (ret)
2209 {
2210 switch (ret)
2211 {
2212 case RMAP_RULE_MISSING:
2213 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2214 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002215 case RMAP_COMPILE_ERROR:
2216 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2217 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002218 }
2219 }
2220 return CMD_SUCCESS;
2221}
2222
2223/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002224static int
paul718e3742002-12-13 20:15:29 +00002225bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002226 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002227{
2228 int ret;
2229
2230 ret = route_map_delete_match (index, command, arg);
2231 if (ret)
2232 {
2233 switch (ret)
2234 {
2235 case RMAP_RULE_MISSING:
2236 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2237 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002238 case RMAP_COMPILE_ERROR:
2239 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2240 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002241 }
2242 }
2243 return CMD_SUCCESS;
2244}
2245
2246/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002247static int
paul718e3742002-12-13 20:15:29 +00002248bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002249 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002250{
2251 int ret;
2252
2253 ret = route_map_add_set (index, command, arg);
2254 if (ret)
2255 {
2256 switch (ret)
2257 {
2258 case RMAP_RULE_MISSING:
2259 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2260 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002261 case RMAP_COMPILE_ERROR:
2262 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2263 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002264 }
2265 }
2266 return CMD_SUCCESS;
2267}
2268
2269/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002270static int
paul718e3742002-12-13 20:15:29 +00002271bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002272 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002273{
2274 int ret;
2275
2276 ret = route_map_delete_set (index, command, arg);
2277 if (ret)
2278 {
2279 switch (ret)
2280 {
2281 case RMAP_RULE_MISSING:
2282 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2283 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002284 case RMAP_COMPILE_ERROR:
2285 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2286 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002287 }
2288 }
2289 return CMD_SUCCESS;
2290}
2291
2292/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002293static void
paulfd79ac92004-10-13 05:06:08 +00002294bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002295{
2296 int i;
2297 afi_t afi;
2298 safi_t safi;
2299 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002300 struct listnode *node, *nnode;
2301 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002302 struct bgp *bgp;
2303 struct peer *peer;
2304 struct peer_group *group;
2305 struct bgp_filter *filter;
2306 struct bgp_node *bn;
2307 struct bgp_static *bgp_static;
2308
2309 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002310 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002311 {
paul1eb8ef22005-04-07 07:30:20 +00002312 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002313 {
2314 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2315 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2316 {
2317 filter = &peer->filter[afi][safi];
2318
paulfee0f4c2004-09-13 05:12:46 +00002319 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002320 {
2321 if (filter->map[direct].name)
2322 filter->map[direct].map =
2323 route_map_lookup_by_name (filter->map[direct].name);
2324 else
2325 filter->map[direct].map = NULL;
2326 }
2327
2328 if (filter->usmap.name)
2329 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2330 else
2331 filter->usmap.map = NULL;
2332 }
2333 }
paul1eb8ef22005-04-07 07:30:20 +00002334 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002335 {
2336 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2337 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2338 {
2339 filter = &group->conf->filter[afi][safi];
2340
paulfee0f4c2004-09-13 05:12:46 +00002341 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002342 {
2343 if (filter->map[direct].name)
2344 filter->map[direct].map =
2345 route_map_lookup_by_name (filter->map[direct].name);
2346 else
2347 filter->map[direct].map = NULL;
2348 }
2349
2350 if (filter->usmap.name)
2351 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2352 else
2353 filter->usmap.map = NULL;
2354 }
2355 }
2356 }
2357
2358 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002359 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002360 {
paul1eb8ef22005-04-07 07:30:20 +00002361 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002362 {
2363 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2364 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2365 {
2366 if (peer->default_rmap[afi][safi].name)
2367 peer->default_rmap[afi][safi].map =
2368 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2369 else
2370 peer->default_rmap[afi][safi].map = NULL;
2371 }
2372 }
2373 }
2374
2375 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002376 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002377 {
2378 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2379 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2380 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2381 bn = bgp_route_next (bn))
2382 if ((bgp_static = bn->info) != NULL)
2383 {
2384 if (bgp_static->rmap.name)
2385 bgp_static->rmap.map =
2386 route_map_lookup_by_name (bgp_static->rmap.name);
2387 else
2388 bgp_static->rmap.map = NULL;
2389 }
2390 }
2391
2392 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002393 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002394 {
2395 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2396 {
2397 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2398 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2399 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2400#ifdef HAVE_IPV6
2401 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2402 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2403 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2404#endif /* HAVE_IPV6 */
2405 }
2406 }
2407}
2408
paulfee0f4c2004-09-13 05:12:46 +00002409DEFUN (match_peer,
2410 match_peer_cmd,
2411 "match peer (A.B.C.D|X:X::X:X)",
2412 MATCH_STR
2413 "Match peer address\n"
2414 "IPv6 address of peer\n"
2415 "IP address of peer\n")
2416{
2417 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2418}
2419
2420DEFUN (match_peer_local,
2421 match_peer_local_cmd,
2422 "match peer local",
2423 MATCH_STR
2424 "Match peer address\n"
2425 "Static or Redistributed routes\n")
2426{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002427 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002428}
2429
2430DEFUN (no_match_peer,
2431 no_match_peer_cmd,
2432 "no match peer",
2433 NO_STR
2434 MATCH_STR
2435 "Match peer address\n")
2436{
2437 if (argc == 0)
2438 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2439
2440 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2441}
2442
2443ALIAS (no_match_peer,
2444 no_match_peer_val_cmd,
2445 "no match peer (A.B.C.D|X:X::X:X)",
2446 NO_STR
2447 MATCH_STR
2448 "Match peer address\n"
2449 "IPv6 address of peer\n"
2450 "IP address of peer\n")
2451
2452ALIAS (no_match_peer,
2453 no_match_peer_local_cmd,
2454 "no match peer local",
2455 NO_STR
2456 MATCH_STR
2457 "Match peer address\n"
2458 "Static or Redistributed routes\n")
2459
paul718e3742002-12-13 20:15:29 +00002460DEFUN (match_ip_address,
2461 match_ip_address_cmd,
2462 "match ip address (<1-199>|<1300-2699>|WORD)",
2463 MATCH_STR
2464 IP_STR
2465 "Match address of route\n"
2466 "IP access-list number\n"
2467 "IP access-list number (expanded range)\n"
2468 "IP Access-list name\n")
2469{
2470 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2471}
2472
2473DEFUN (no_match_ip_address,
2474 no_match_ip_address_cmd,
2475 "no match ip address",
2476 NO_STR
2477 MATCH_STR
2478 IP_STR
2479 "Match address of route\n")
2480{
2481 if (argc == 0)
2482 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2483
2484 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2485}
2486
2487ALIAS (no_match_ip_address,
2488 no_match_ip_address_val_cmd,
2489 "no match ip address (<1-199>|<1300-2699>|WORD)",
2490 NO_STR
2491 MATCH_STR
2492 IP_STR
2493 "Match address of route\n"
2494 "IP access-list number\n"
2495 "IP access-list number (expanded range)\n"
2496 "IP Access-list name\n")
2497
2498DEFUN (match_ip_next_hop,
2499 match_ip_next_hop_cmd,
2500 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2501 MATCH_STR
2502 IP_STR
2503 "Match next-hop address of route\n"
2504 "IP access-list number\n"
2505 "IP access-list number (expanded range)\n"
2506 "IP Access-list name\n")
2507{
2508 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2509}
2510
2511DEFUN (no_match_ip_next_hop,
2512 no_match_ip_next_hop_cmd,
2513 "no match ip next-hop",
2514 NO_STR
2515 MATCH_STR
2516 IP_STR
2517 "Match next-hop address of route\n")
2518{
2519 if (argc == 0)
2520 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2521
2522 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2523}
2524
2525ALIAS (no_match_ip_next_hop,
2526 no_match_ip_next_hop_val_cmd,
2527 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2528 NO_STR
2529 MATCH_STR
2530 IP_STR
2531 "Match next-hop address of route\n"
2532 "IP access-list number\n"
2533 "IP access-list number (expanded range)\n"
2534 "IP Access-list name\n")
2535
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002536/* match probability { */
2537
2538DEFUN (match_probability,
2539 match_probability_cmd,
2540 "match probability <0-100>",
2541 MATCH_STR
2542 "Match portion of routes defined by percentage value\n"
2543 "Percentage of routes\n")
2544{
2545 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2546}
2547
2548DEFUN (no_match_probability,
2549 no_match_probability_cmd,
2550 "no match probability",
2551 NO_STR
2552 MATCH_STR
2553 "Match portion of routes defined by percentage value\n")
2554{
2555 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2556}
2557
2558ALIAS (no_match_probability,
2559 no_match_probability_val_cmd,
2560 "no match probability <1-99>",
2561 NO_STR
2562 MATCH_STR
2563 "Match portion of routes defined by percentage value\n"
2564 "Percentage of routes\n")
2565
2566/* } */
2567
hassoc1643bb2005-02-02 16:43:17 +00002568DEFUN (match_ip_route_source,
2569 match_ip_route_source_cmd,
2570 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2571 MATCH_STR
2572 IP_STR
2573 "Match advertising source address of route\n"
2574 "IP access-list number\n"
2575 "IP access-list number (expanded range)\n"
2576 "IP standard access-list name\n")
2577{
2578 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2579}
2580
2581DEFUN (no_match_ip_route_source,
2582 no_match_ip_route_source_cmd,
2583 "no match ip route-source",
2584 NO_STR
2585 MATCH_STR
2586 IP_STR
2587 "Match advertising source address of route\n")
2588{
2589 if (argc == 0)
2590 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2591
2592 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2593}
2594
2595ALIAS (no_match_ip_route_source,
2596 no_match_ip_route_source_val_cmd,
2597 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2598 NO_STR
2599 MATCH_STR
2600 IP_STR
2601 "Match advertising source address of route\n"
2602 "IP access-list number\n"
2603 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002604 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002605
paul718e3742002-12-13 20:15:29 +00002606DEFUN (match_ip_address_prefix_list,
2607 match_ip_address_prefix_list_cmd,
2608 "match ip address prefix-list WORD",
2609 MATCH_STR
2610 IP_STR
2611 "Match address of route\n"
2612 "Match entries of prefix-lists\n"
2613 "IP prefix-list name\n")
2614{
2615 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2616}
2617
2618DEFUN (no_match_ip_address_prefix_list,
2619 no_match_ip_address_prefix_list_cmd,
2620 "no match ip address prefix-list",
2621 NO_STR
2622 MATCH_STR
2623 IP_STR
2624 "Match address of route\n"
2625 "Match entries of prefix-lists\n")
2626{
2627 if (argc == 0)
2628 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2629
2630 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2631}
2632
2633ALIAS (no_match_ip_address_prefix_list,
2634 no_match_ip_address_prefix_list_val_cmd,
2635 "no match ip address prefix-list WORD",
2636 NO_STR
2637 MATCH_STR
2638 IP_STR
2639 "Match address of route\n"
2640 "Match entries of prefix-lists\n"
2641 "IP prefix-list name\n")
2642
2643DEFUN (match_ip_next_hop_prefix_list,
2644 match_ip_next_hop_prefix_list_cmd,
2645 "match ip next-hop prefix-list WORD",
2646 MATCH_STR
2647 IP_STR
2648 "Match next-hop address of route\n"
2649 "Match entries of prefix-lists\n"
2650 "IP prefix-list name\n")
2651{
2652 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2653}
2654
2655DEFUN (no_match_ip_next_hop_prefix_list,
2656 no_match_ip_next_hop_prefix_list_cmd,
2657 "no match ip next-hop prefix-list",
2658 NO_STR
2659 MATCH_STR
2660 IP_STR
2661 "Match next-hop address of route\n"
2662 "Match entries of prefix-lists\n")
2663{
2664 if (argc == 0)
2665 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2666
2667 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2668}
2669
2670ALIAS (no_match_ip_next_hop_prefix_list,
2671 no_match_ip_next_hop_prefix_list_val_cmd,
2672 "no match ip next-hop prefix-list WORD",
2673 NO_STR
2674 MATCH_STR
2675 IP_STR
2676 "Match next-hop address of route\n"
2677 "Match entries of prefix-lists\n"
2678 "IP prefix-list name\n")
2679
hassoc1643bb2005-02-02 16:43:17 +00002680DEFUN (match_ip_route_source_prefix_list,
2681 match_ip_route_source_prefix_list_cmd,
2682 "match ip route-source prefix-list WORD",
2683 MATCH_STR
2684 IP_STR
2685 "Match advertising source address of route\n"
2686 "Match entries of prefix-lists\n"
2687 "IP prefix-list name\n")
2688{
2689 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2690}
2691
2692DEFUN (no_match_ip_route_source_prefix_list,
2693 no_match_ip_route_source_prefix_list_cmd,
2694 "no match ip route-source prefix-list",
2695 NO_STR
2696 MATCH_STR
2697 IP_STR
2698 "Match advertising source address of route\n"
2699 "Match entries of prefix-lists\n")
2700{
2701 if (argc == 0)
2702 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2703
2704 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2705}
2706
2707ALIAS (no_match_ip_route_source_prefix_list,
2708 no_match_ip_route_source_prefix_list_val_cmd,
2709 "no match ip route-source prefix-list WORD",
2710 NO_STR
2711 MATCH_STR
2712 IP_STR
2713 "Match advertising source address of route\n"
2714 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002715 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002716
paul718e3742002-12-13 20:15:29 +00002717DEFUN (match_metric,
2718 match_metric_cmd,
2719 "match metric <0-4294967295>",
2720 MATCH_STR
2721 "Match metric of route\n"
2722 "Metric value\n")
2723{
2724 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2725}
2726
2727DEFUN (no_match_metric,
2728 no_match_metric_cmd,
2729 "no match metric",
2730 NO_STR
2731 MATCH_STR
2732 "Match metric of route\n")
2733{
2734 if (argc == 0)
2735 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2736
2737 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2738}
2739
2740ALIAS (no_match_metric,
2741 no_match_metric_val_cmd,
2742 "no match metric <0-4294967295>",
2743 NO_STR
2744 MATCH_STR
2745 "Match metric of route\n"
2746 "Metric value\n")
2747
2748DEFUN (match_community,
2749 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002750 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002751 MATCH_STR
2752 "Match BGP community list\n"
2753 "Community-list number (standard)\n"
2754 "Community-list number (expanded)\n"
2755 "Community-list name\n")
2756{
2757 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2758}
2759
2760DEFUN (match_community_exact,
2761 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002762 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002763 MATCH_STR
2764 "Match BGP community list\n"
2765 "Community-list number (standard)\n"
2766 "Community-list number (expanded)\n"
2767 "Community-list name\n"
2768 "Do exact matching of communities\n")
2769{
2770 int ret;
2771 char *argstr;
2772
2773 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2774 strlen (argv[0]) + strlen ("exact-match") + 2);
2775
2776 sprintf (argstr, "%s exact-match", argv[0]);
2777
2778 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2779
2780 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2781
2782 return ret;
2783}
2784
2785DEFUN (no_match_community,
2786 no_match_community_cmd,
2787 "no match community",
2788 NO_STR
2789 MATCH_STR
2790 "Match BGP community list\n")
2791{
2792 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2793}
2794
2795ALIAS (no_match_community,
2796 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002797 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002798 NO_STR
2799 MATCH_STR
2800 "Match BGP community list\n"
2801 "Community-list number (standard)\n"
2802 "Community-list number (expanded)\n"
2803 "Community-list name\n")
2804
2805ALIAS (no_match_community,
2806 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002807 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002808 NO_STR
2809 MATCH_STR
2810 "Match BGP community list\n"
2811 "Community-list number (standard)\n"
2812 "Community-list number (expanded)\n"
2813 "Community-list name\n"
2814 "Do exact matching of communities\n")
2815
paul73ffb252003-04-19 15:49:49 +00002816DEFUN (match_ecommunity,
2817 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002818 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002819 MATCH_STR
2820 "Match BGP/VPN extended community list\n"
2821 "Extended community-list number (standard)\n"
2822 "Extended community-list number (expanded)\n"
2823 "Extended community-list name\n")
2824{
2825 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2826}
2827
2828DEFUN (no_match_ecommunity,
2829 no_match_ecommunity_cmd,
2830 "no match extcommunity",
2831 NO_STR
2832 MATCH_STR
2833 "Match BGP/VPN extended community list\n")
2834{
2835 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2836}
2837
2838ALIAS (no_match_ecommunity,
2839 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002840 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002841 NO_STR
2842 MATCH_STR
2843 "Match BGP/VPN extended community list\n"
2844 "Extended community-list number (standard)\n"
2845 "Extended community-list number (expanded)\n"
2846 "Extended community-list name\n")
2847
paul718e3742002-12-13 20:15:29 +00002848DEFUN (match_aspath,
2849 match_aspath_cmd,
2850 "match as-path WORD",
2851 MATCH_STR
2852 "Match BGP AS path list\n"
2853 "AS path access-list name\n")
2854{
2855 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2856}
2857
2858DEFUN (no_match_aspath,
2859 no_match_aspath_cmd,
2860 "no match as-path",
2861 NO_STR
2862 MATCH_STR
2863 "Match BGP AS path list\n")
2864{
2865 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2866}
2867
2868ALIAS (no_match_aspath,
2869 no_match_aspath_val_cmd,
2870 "no match as-path WORD",
2871 NO_STR
2872 MATCH_STR
2873 "Match BGP AS path list\n"
2874 "AS path access-list name\n")
2875
2876DEFUN (match_origin,
2877 match_origin_cmd,
2878 "match origin (egp|igp|incomplete)",
2879 MATCH_STR
2880 "BGP origin code\n"
2881 "remote EGP\n"
2882 "local IGP\n"
2883 "unknown heritage\n")
2884{
2885 if (strncmp (argv[0], "igp", 2) == 0)
2886 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2887 if (strncmp (argv[0], "egp", 1) == 0)
2888 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2889 if (strncmp (argv[0], "incomplete", 2) == 0)
2890 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2891
2892 return CMD_WARNING;
2893}
2894
2895DEFUN (no_match_origin,
2896 no_match_origin_cmd,
2897 "no match origin",
2898 NO_STR
2899 MATCH_STR
2900 "BGP origin code\n")
2901{
2902 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2903}
2904
2905ALIAS (no_match_origin,
2906 no_match_origin_val_cmd,
2907 "no match origin (egp|igp|incomplete)",
2908 NO_STR
2909 MATCH_STR
2910 "BGP origin code\n"
2911 "remote EGP\n"
2912 "local IGP\n"
2913 "unknown heritage\n")
2914
2915DEFUN (set_ip_nexthop,
2916 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002917 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002918 SET_STR
2919 IP_STR
2920 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002921 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002922{
2923 union sockunion su;
2924 int ret;
2925
2926 ret = str2sockunion (argv[0], &su);
2927 if (ret < 0)
2928 {
2929 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2930 return CMD_WARNING;
2931 }
2932
2933 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2934}
2935
paulaf5cd0a2003-11-02 07:24:40 +00002936DEFUN (set_ip_nexthop_peer,
2937 set_ip_nexthop_peer_cmd,
2938 "set ip next-hop peer-address",
2939 SET_STR
2940 IP_STR
2941 "Next hop address\n"
2942 "Use peer address (for BGP only)\n")
2943{
2944 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2945}
2946
paul94f2b392005-06-28 12:44:16 +00002947DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002948 no_set_ip_nexthop_peer_cmd,
2949 "no set ip next-hop peer-address",
2950 NO_STR
2951 SET_STR
2952 IP_STR
2953 "Next hop address\n"
2954 "Use peer address (for BGP only)\n")
2955{
2956 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2957}
2958
2959
paul718e3742002-12-13 20:15:29 +00002960DEFUN (no_set_ip_nexthop,
2961 no_set_ip_nexthop_cmd,
2962 "no set ip next-hop",
2963 NO_STR
2964 SET_STR
paul718e3742002-12-13 20:15:29 +00002965 "Next hop address\n")
2966{
paulaf5cd0a2003-11-02 07:24:40 +00002967 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002968 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2969
2970 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2971}
2972
2973ALIAS (no_set_ip_nexthop,
2974 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002975 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002976 NO_STR
2977 SET_STR
2978 IP_STR
2979 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002980 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002981
2982DEFUN (set_metric,
2983 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002984 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002985 SET_STR
2986 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002987 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002988{
2989 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2990}
2991
paul73ffb252003-04-19 15:49:49 +00002992ALIAS (set_metric,
2993 set_metric_addsub_cmd,
2994 "set metric <+/-metric>",
2995 SET_STR
2996 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002997 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002998
paul718e3742002-12-13 20:15:29 +00002999DEFUN (no_set_metric,
3000 no_set_metric_cmd,
3001 "no set metric",
3002 NO_STR
3003 SET_STR
3004 "Metric value for destination routing protocol\n")
3005{
3006 if (argc == 0)
3007 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3008
3009 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3010}
3011
3012ALIAS (no_set_metric,
3013 no_set_metric_val_cmd,
3014 "no set metric <0-4294967295>",
3015 NO_STR
3016 SET_STR
3017 "Metric value for destination routing protocol\n"
3018 "Metric value\n")
3019
3020DEFUN (set_local_pref,
3021 set_local_pref_cmd,
3022 "set local-preference <0-4294967295>",
3023 SET_STR
3024 "BGP local preference path attribute\n"
3025 "Preference value\n")
3026{
3027 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3028}
3029
3030DEFUN (no_set_local_pref,
3031 no_set_local_pref_cmd,
3032 "no set local-preference",
3033 NO_STR
3034 SET_STR
3035 "BGP local preference path attribute\n")
3036{
3037 if (argc == 0)
3038 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3039
3040 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3041}
3042
3043ALIAS (no_set_local_pref,
3044 no_set_local_pref_val_cmd,
3045 "no set local-preference <0-4294967295>",
3046 NO_STR
3047 SET_STR
3048 "BGP local preference path attribute\n"
3049 "Preference value\n")
3050
3051DEFUN (set_weight,
3052 set_weight_cmd,
3053 "set weight <0-4294967295>",
3054 SET_STR
3055 "BGP weight for routing table\n"
3056 "Weight value\n")
3057{
3058 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3059}
3060
3061DEFUN (no_set_weight,
3062 no_set_weight_cmd,
3063 "no set weight",
3064 NO_STR
3065 SET_STR
3066 "BGP weight for routing table\n")
3067{
3068 if (argc == 0)
3069 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3070
3071 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3072}
3073
3074ALIAS (no_set_weight,
3075 no_set_weight_val_cmd,
3076 "no set weight <0-4294967295>",
3077 NO_STR
3078 SET_STR
3079 "BGP weight for routing table\n"
3080 "Weight value\n")
3081
3082DEFUN (set_aspath_prepend,
3083 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003084 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003085 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003086 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003087 "Prepend to the as-path\n"
3088 "AS number\n")
3089{
3090 int ret;
3091 char *str;
3092
3093 str = argv_concat (argv, argc, 0);
3094 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3095 XFREE (MTYPE_TMP, str);
3096
3097 return ret;
3098}
3099
3100DEFUN (no_set_aspath_prepend,
3101 no_set_aspath_prepend_cmd,
3102 "no set as-path prepend",
3103 NO_STR
3104 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003105 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003106 "Prepend to the as-path\n")
3107{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003108 int ret;
3109 char *str;
3110
3111 if (argc == 0)
3112 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3113
3114 str = argv_concat (argv, argc, 0);
3115 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3116 XFREE (MTYPE_TMP, str);
3117 return ret;
paul718e3742002-12-13 20:15:29 +00003118}
3119
3120ALIAS (no_set_aspath_prepend,
3121 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003122 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003123 NO_STR
3124 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003125 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003126 "Prepend to the as-path\n"
3127 "AS number\n")
3128
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003129DEFUN (set_aspath_exclude,
3130 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003131 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003132 SET_STR
3133 "Transform BGP AS-path attribute\n"
3134 "Exclude from the as-path\n"
3135 "AS number\n")
3136{
3137 int ret;
3138 char *str;
3139
3140 str = argv_concat (argv, argc, 0);
3141 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3142 XFREE (MTYPE_TMP, str);
3143 return ret;
3144}
3145
3146DEFUN (no_set_aspath_exclude,
3147 no_set_aspath_exclude_cmd,
3148 "no set as-path exclude",
3149 NO_STR
3150 SET_STR
3151 "Transform BGP AS_PATH attribute\n"
3152 "Exclude from the as-path\n")
3153{
3154 int ret;
3155 char *str;
3156
3157 if (argc == 0)
3158 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3159
3160 str = argv_concat (argv, argc, 0);
3161 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3162 XFREE (MTYPE_TMP, str);
3163 return ret;
3164}
3165
3166ALIAS (no_set_aspath_exclude,
3167 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003168 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003169 NO_STR
3170 SET_STR
3171 "Transform BGP AS_PATH attribute\n"
3172 "Exclude from the as-path\n"
3173 "AS number\n")
3174
paul718e3742002-12-13 20:15:29 +00003175DEFUN (set_community,
3176 set_community_cmd,
3177 "set community .AA:NN",
3178 SET_STR
3179 "BGP community attribute\n"
3180 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3181{
3182 int i;
3183 int first = 0;
3184 int additive = 0;
3185 struct buffer *b;
3186 struct community *com = NULL;
3187 char *str;
3188 char *argstr;
3189 int ret;
3190
3191 b = buffer_new (1024);
3192
3193 for (i = 0; i < argc; i++)
3194 {
3195 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3196 {
3197 additive = 1;
3198 continue;
3199 }
3200
3201 if (first)
3202 buffer_putc (b, ' ');
3203 else
3204 first = 1;
3205
3206 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3207 {
3208 buffer_putstr (b, "internet");
3209 continue;
3210 }
3211 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3212 {
3213 buffer_putstr (b, "local-AS");
3214 continue;
3215 }
3216 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3217 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3218 {
3219 buffer_putstr (b, "no-advertise");
3220 continue;
3221 }
3222 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3223 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3224 {
3225 buffer_putstr (b, "no-export");
3226 continue;
3227 }
3228 buffer_putstr (b, argv[i]);
3229 }
3230 buffer_putc (b, '\0');
3231
3232 /* Fetch result string then compile it to communities attribute. */
3233 str = buffer_getstr (b);
3234 buffer_free (b);
3235
3236 if (str)
3237 {
3238 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003239 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003240 }
3241
3242 /* Can't compile user input into communities attribute. */
3243 if (! com)
3244 {
3245 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3246 return CMD_WARNING;
3247 }
3248
3249 /* Set communites attribute string. */
3250 str = community_str (com);
3251
3252 if (additive)
3253 {
3254 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3255 strcpy (argstr, str);
3256 strcpy (argstr + strlen (str), " additive");
3257 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3258 XFREE (MTYPE_TMP, argstr);
3259 }
3260 else
3261 ret = bgp_route_set_add (vty, vty->index, "community", str);
3262
3263 community_free (com);
3264
3265 return ret;
3266}
3267
3268DEFUN (set_community_none,
3269 set_community_none_cmd,
3270 "set community none",
3271 SET_STR
3272 "BGP community attribute\n"
3273 "No community attribute\n")
3274{
3275 return bgp_route_set_add (vty, vty->index, "community", "none");
3276}
3277
3278DEFUN (no_set_community,
3279 no_set_community_cmd,
3280 "no set community",
3281 NO_STR
3282 SET_STR
3283 "BGP community attribute\n")
3284{
3285 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3286}
3287
3288ALIAS (no_set_community,
3289 no_set_community_val_cmd,
3290 "no set community .AA:NN",
3291 NO_STR
3292 SET_STR
3293 "BGP community attribute\n"
3294 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3295
3296ALIAS (no_set_community,
3297 no_set_community_none_cmd,
3298 "no set community none",
3299 NO_STR
3300 SET_STR
3301 "BGP community attribute\n"
3302 "No community attribute\n")
3303
3304DEFUN (set_community_delete,
3305 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003306 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003307 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{
3314 char *str;
3315
3316 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3317 strcpy (str, argv[0]);
3318 strcpy (str + strlen (argv[0]), " delete");
3319
3320 bgp_route_set_add (vty, vty->index, "comm-list", str);
3321
3322 XFREE (MTYPE_TMP, str);
3323 return CMD_SUCCESS;
3324}
3325
3326DEFUN (no_set_community_delete,
3327 no_set_community_delete_cmd,
3328 "no set comm-list",
3329 NO_STR
3330 SET_STR
3331 "set BGP community list (for deletion)\n")
3332{
3333 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3334}
3335
3336ALIAS (no_set_community_delete,
3337 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003338 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003339 NO_STR
3340 SET_STR
3341 "set BGP community list (for deletion)\n"
3342 "Community-list number (standard)\n"
3343 "Communitly-list number (expanded)\n"
3344 "Community-list name\n"
3345 "Delete matching communities\n")
3346
3347DEFUN (set_ecommunity_rt,
3348 set_ecommunity_rt_cmd,
3349 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3350 SET_STR
3351 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003352 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003353 "VPN extended community\n")
3354{
3355 int ret;
3356 char *str;
3357
3358 str = argv_concat (argv, argc, 0);
3359 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3360 XFREE (MTYPE_TMP, str);
3361
3362 return ret;
3363}
3364
3365DEFUN (no_set_ecommunity_rt,
3366 no_set_ecommunity_rt_cmd,
3367 "no set extcommunity rt",
3368 NO_STR
3369 SET_STR
3370 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003371 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003372{
3373 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3374}
3375
3376ALIAS (no_set_ecommunity_rt,
3377 no_set_ecommunity_rt_val_cmd,
3378 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3379 NO_STR
3380 SET_STR
3381 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003382 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003383 "VPN extended community\n")
3384
3385DEFUN (set_ecommunity_soo,
3386 set_ecommunity_soo_cmd,
3387 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3388 SET_STR
3389 "BGP extended community attribute\n"
3390 "Site-of-Origin extended community\n"
3391 "VPN extended community\n")
3392{
3393 int ret;
3394 char *str;
3395
3396 str = argv_concat (argv, argc, 0);
3397 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3398 XFREE (MTYPE_TMP, str);
3399 return ret;
3400}
3401
3402DEFUN (no_set_ecommunity_soo,
3403 no_set_ecommunity_soo_cmd,
3404 "no set extcommunity soo",
3405 NO_STR
3406 SET_STR
3407 "BGP extended community attribute\n"
3408 "Site-of-Origin extended community\n")
3409{
3410 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3411}
3412
3413ALIAS (no_set_ecommunity_soo,
3414 no_set_ecommunity_soo_val_cmd,
3415 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3416 NO_STR
3417 SET_STR
3418 "BGP extended community attribute\n"
3419 "Site-of-Origin extended community\n"
3420 "VPN extended community\n")
3421
3422DEFUN (set_origin,
3423 set_origin_cmd,
3424 "set origin (egp|igp|incomplete)",
3425 SET_STR
3426 "BGP origin code\n"
3427 "remote EGP\n"
3428 "local IGP\n"
3429 "unknown heritage\n")
3430{
3431 if (strncmp (argv[0], "igp", 2) == 0)
3432 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3433 if (strncmp (argv[0], "egp", 1) == 0)
3434 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3435 if (strncmp (argv[0], "incomplete", 2) == 0)
3436 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3437
3438 return CMD_WARNING;
3439}
3440
3441DEFUN (no_set_origin,
3442 no_set_origin_cmd,
3443 "no set origin",
3444 NO_STR
3445 SET_STR
3446 "BGP origin code\n")
3447{
3448 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3449}
3450
3451ALIAS (no_set_origin,
3452 no_set_origin_val_cmd,
3453 "no set origin (egp|igp|incomplete)",
3454 NO_STR
3455 SET_STR
3456 "BGP origin code\n"
3457 "remote EGP\n"
3458 "local IGP\n"
3459 "unknown heritage\n")
3460
3461DEFUN (set_atomic_aggregate,
3462 set_atomic_aggregate_cmd,
3463 "set atomic-aggregate",
3464 SET_STR
3465 "BGP atomic aggregate attribute\n" )
3466{
3467 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3468}
3469
3470DEFUN (no_set_atomic_aggregate,
3471 no_set_atomic_aggregate_cmd,
3472 "no set atomic-aggregate",
3473 NO_STR
3474 SET_STR
3475 "BGP atomic aggregate attribute\n" )
3476{
3477 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3478}
3479
3480DEFUN (set_aggregator_as,
3481 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003482 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003483 SET_STR
3484 "BGP aggregator attribute\n"
3485 "AS number of aggregator\n"
3486 "AS number\n"
3487 "IP address of aggregator\n")
3488{
3489 int ret;
3490 as_t as;
3491 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003492 char *argstr;
3493
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003494 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003495
paul718e3742002-12-13 20:15:29 +00003496 ret = inet_aton (argv[1], &address);
3497 if (ret == 0)
3498 {
3499 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3500 return CMD_WARNING;
3501 }
3502
3503 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3504 strlen (argv[0]) + strlen (argv[1]) + 2);
3505
3506 sprintf (argstr, "%s %s", argv[0], argv[1]);
3507
3508 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3509
3510 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3511
3512 return ret;
3513}
3514
3515DEFUN (no_set_aggregator_as,
3516 no_set_aggregator_as_cmd,
3517 "no set aggregator as",
3518 NO_STR
3519 SET_STR
3520 "BGP aggregator attribute\n"
3521 "AS number of aggregator\n")
3522{
3523 int ret;
3524 as_t as;
3525 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003526 char *argstr;
3527
3528 if (argv == 0)
3529 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3530
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003531 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003532
3533 ret = inet_aton (argv[1], &address);
3534 if (ret == 0)
3535 {
3536 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3537 return CMD_WARNING;
3538 }
3539
3540 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3541 strlen (argv[0]) + strlen (argv[1]) + 2);
3542
3543 sprintf (argstr, "%s %s", argv[0], argv[1]);
3544
3545 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3546
3547 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3548
3549 return ret;
3550}
3551
3552ALIAS (no_set_aggregator_as,
3553 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003554 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003555 NO_STR
3556 SET_STR
3557 "BGP aggregator attribute\n"
3558 "AS number of aggregator\n"
3559 "AS number\n"
3560 "IP address of aggregator\n")
3561
3562
3563#ifdef HAVE_IPV6
3564DEFUN (match_ipv6_address,
3565 match_ipv6_address_cmd,
3566 "match ipv6 address WORD",
3567 MATCH_STR
3568 IPV6_STR
3569 "Match IPv6 address of route\n"
3570 "IPv6 access-list name\n")
3571{
3572 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3573}
3574
3575DEFUN (no_match_ipv6_address,
3576 no_match_ipv6_address_cmd,
3577 "no match ipv6 address WORD",
3578 NO_STR
3579 MATCH_STR
3580 IPV6_STR
3581 "Match IPv6 address of route\n"
3582 "IPv6 access-list name\n")
3583{
3584 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3585}
3586
3587DEFUN (match_ipv6_next_hop,
3588 match_ipv6_next_hop_cmd,
3589 "match ipv6 next-hop X:X::X:X",
3590 MATCH_STR
3591 IPV6_STR
3592 "Match IPv6 next-hop address of route\n"
3593 "IPv6 address of next hop\n")
3594{
3595 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3596}
3597
3598DEFUN (no_match_ipv6_next_hop,
3599 no_match_ipv6_next_hop_cmd,
3600 "no match ipv6 next-hop X:X::X:X",
3601 NO_STR
3602 MATCH_STR
3603 IPV6_STR
3604 "Match IPv6 next-hop address of route\n"
3605 "IPv6 address of next hop\n")
3606{
3607 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3608}
3609
3610DEFUN (match_ipv6_address_prefix_list,
3611 match_ipv6_address_prefix_list_cmd,
3612 "match ipv6 address prefix-list WORD",
3613 MATCH_STR
3614 IPV6_STR
3615 "Match address of route\n"
3616 "Match entries of prefix-lists\n"
3617 "IP prefix-list name\n")
3618{
3619 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3620}
3621
3622DEFUN (no_match_ipv6_address_prefix_list,
3623 no_match_ipv6_address_prefix_list_cmd,
3624 "no match ipv6 address prefix-list WORD",
3625 NO_STR
3626 MATCH_STR
3627 IPV6_STR
3628 "Match address of route\n"
3629 "Match entries of prefix-lists\n"
3630 "IP prefix-list name\n")
3631{
3632 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3633}
3634
3635DEFUN (set_ipv6_nexthop_global,
3636 set_ipv6_nexthop_global_cmd,
3637 "set ipv6 next-hop global X:X::X:X",
3638 SET_STR
3639 IPV6_STR
3640 "IPv6 next-hop address\n"
3641 "IPv6 global address\n"
3642 "IPv6 address of next hop\n")
3643{
3644 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3645}
3646
3647DEFUN (no_set_ipv6_nexthop_global,
3648 no_set_ipv6_nexthop_global_cmd,
3649 "no set ipv6 next-hop global",
3650 NO_STR
3651 SET_STR
3652 IPV6_STR
3653 "IPv6 next-hop address\n"
3654 "IPv6 global address\n")
3655{
3656 if (argc == 0)
3657 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3658
3659 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3660}
3661
3662ALIAS (no_set_ipv6_nexthop_global,
3663 no_set_ipv6_nexthop_global_val_cmd,
3664 "no set ipv6 next-hop global X:X::X:X",
3665 NO_STR
3666 SET_STR
3667 IPV6_STR
3668 "IPv6 next-hop address\n"
3669 "IPv6 global address\n"
3670 "IPv6 address of next hop\n")
3671
3672DEFUN (set_ipv6_nexthop_local,
3673 set_ipv6_nexthop_local_cmd,
3674 "set ipv6 next-hop local X:X::X:X",
3675 SET_STR
3676 IPV6_STR
3677 "IPv6 next-hop address\n"
3678 "IPv6 local address\n"
3679 "IPv6 address of next hop\n")
3680{
3681 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3682}
3683
3684DEFUN (no_set_ipv6_nexthop_local,
3685 no_set_ipv6_nexthop_local_cmd,
3686 "no set ipv6 next-hop local",
3687 NO_STR
3688 SET_STR
3689 IPV6_STR
3690 "IPv6 next-hop address\n"
3691 "IPv6 local address\n")
3692{
3693 if (argc == 0)
3694 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3695
3696 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3697}
3698
3699ALIAS (no_set_ipv6_nexthop_local,
3700 no_set_ipv6_nexthop_local_val_cmd,
3701 "no set ipv6 next-hop local X:X::X:X",
3702 NO_STR
3703 SET_STR
3704 IPV6_STR
3705 "IPv6 next-hop address\n"
3706 "IPv6 local address\n"
3707 "IPv6 address of next hop\n")
3708#endif /* HAVE_IPV6 */
3709
3710DEFUN (set_vpnv4_nexthop,
3711 set_vpnv4_nexthop_cmd,
3712 "set vpnv4 next-hop A.B.C.D",
3713 SET_STR
3714 "VPNv4 information\n"
3715 "VPNv4 next-hop address\n"
3716 "IP address of next hop\n")
3717{
3718 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3719}
3720
3721DEFUN (no_set_vpnv4_nexthop,
3722 no_set_vpnv4_nexthop_cmd,
3723 "no set vpnv4 next-hop",
3724 NO_STR
3725 SET_STR
3726 "VPNv4 information\n"
3727 "VPNv4 next-hop address\n")
3728{
3729 if (argc == 0)
3730 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3731
3732 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3733}
3734
3735ALIAS (no_set_vpnv4_nexthop,
3736 no_set_vpnv4_nexthop_val_cmd,
3737 "no set vpnv4 next-hop A.B.C.D",
3738 NO_STR
3739 SET_STR
3740 "VPNv4 information\n"
3741 "VPNv4 next-hop address\n"
3742 "IP address of next hop\n")
3743
3744DEFUN (set_originator_id,
3745 set_originator_id_cmd,
3746 "set originator-id A.B.C.D",
3747 SET_STR
3748 "BGP originator ID attribute\n"
3749 "IP address of originator\n")
3750{
3751 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3752}
3753
3754DEFUN (no_set_originator_id,
3755 no_set_originator_id_cmd,
3756 "no set originator-id",
3757 NO_STR
3758 SET_STR
3759 "BGP originator ID attribute\n")
3760{
3761 if (argc == 0)
3762 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3763
3764 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3765}
3766
3767ALIAS (no_set_originator_id,
3768 no_set_originator_id_val_cmd,
3769 "no set originator-id A.B.C.D",
3770 NO_STR
3771 SET_STR
3772 "BGP originator ID attribute\n"
3773 "IP address of originator\n")
3774
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003775DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003776 set_pathlimit_ttl_cmd,
3777 "set pathlimit ttl <1-255>",
3778 SET_STR
3779 "BGP AS-Pathlimit attribute\n"
3780 "Set AS-Path Hop-count TTL\n")
3781{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003782 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003783}
3784
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003785DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003786 no_set_pathlimit_ttl_cmd,
3787 "no set pathlimit ttl",
3788 NO_STR
3789 SET_STR
3790 "BGP AS-Pathlimit attribute\n"
3791 "Set AS-Path Hop-count TTL\n")
3792{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003793 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003794}
3795
3796ALIAS (no_set_pathlimit_ttl,
3797 no_set_pathlimit_ttl_val_cmd,
3798 "no set pathlimit ttl <1-255>",
3799 NO_STR
3800 MATCH_STR
3801 "BGP AS-Pathlimit attribute\n"
3802 "Set AS-Path Hop-count TTL\n")
3803
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003804DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003805 match_pathlimit_as_cmd,
3806 "match pathlimit as <1-65535>",
3807 MATCH_STR
3808 "BGP AS-Pathlimit attribute\n"
3809 "Match Pathlimit AS number\n")
3810{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003811 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003812}
3813
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003814DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003815 no_match_pathlimit_as_cmd,
3816 "no match pathlimit as",
3817 NO_STR
3818 MATCH_STR
3819 "BGP AS-Pathlimit attribute\n"
3820 "Match Pathlimit AS number\n")
3821{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003822 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003823}
3824
3825ALIAS (no_match_pathlimit_as,
3826 no_match_pathlimit_as_val_cmd,
3827 "no match pathlimit as <1-65535>",
3828 NO_STR
3829 MATCH_STR
3830 "BGP AS-Pathlimit attribute\n"
3831 "Match Pathlimit ASN\n")
3832
paul718e3742002-12-13 20:15:29 +00003833
3834/* Initialization of route map. */
3835void
paul94f2b392005-06-28 12:44:16 +00003836bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003837{
3838 route_map_init ();
3839 route_map_init_vty ();
3840 route_map_add_hook (bgp_route_map_update);
3841 route_map_delete_hook (bgp_route_map_update);
3842
paulfee0f4c2004-09-13 05:12:46 +00003843 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003844 route_map_install_match (&route_match_ip_address_cmd);
3845 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003846 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003847 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3848 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003849 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003850 route_map_install_match (&route_match_aspath_cmd);
3851 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003852 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003853 route_map_install_match (&route_match_metric_cmd);
3854 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003855 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003856
3857 route_map_install_set (&route_set_ip_nexthop_cmd);
3858 route_map_install_set (&route_set_local_pref_cmd);
3859 route_map_install_set (&route_set_weight_cmd);
3860 route_map_install_set (&route_set_metric_cmd);
3861 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003862 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003863 route_map_install_set (&route_set_origin_cmd);
3864 route_map_install_set (&route_set_atomic_aggregate_cmd);
3865 route_map_install_set (&route_set_aggregator_as_cmd);
3866 route_map_install_set (&route_set_community_cmd);
3867 route_map_install_set (&route_set_community_delete_cmd);
3868 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3869 route_map_install_set (&route_set_originator_id_cmd);
3870 route_map_install_set (&route_set_ecommunity_rt_cmd);
3871 route_map_install_set (&route_set_ecommunity_soo_cmd);
3872
paulfee0f4c2004-09-13 05:12:46 +00003873 install_element (RMAP_NODE, &match_peer_cmd);
3874 install_element (RMAP_NODE, &match_peer_local_cmd);
3875 install_element (RMAP_NODE, &no_match_peer_cmd);
3876 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3877 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003878 install_element (RMAP_NODE, &match_ip_address_cmd);
3879 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3880 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3881 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3882 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3883 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003884 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3885 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3886 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003887 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3888 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3889 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3890 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3891 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3892 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003893 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3894 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3895 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003896
3897 install_element (RMAP_NODE, &match_aspath_cmd);
3898 install_element (RMAP_NODE, &no_match_aspath_cmd);
3899 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3900 install_element (RMAP_NODE, &match_metric_cmd);
3901 install_element (RMAP_NODE, &no_match_metric_cmd);
3902 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3903 install_element (RMAP_NODE, &match_community_cmd);
3904 install_element (RMAP_NODE, &match_community_exact_cmd);
3905 install_element (RMAP_NODE, &no_match_community_cmd);
3906 install_element (RMAP_NODE, &no_match_community_val_cmd);
3907 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003908 install_element (RMAP_NODE, &match_ecommunity_cmd);
3909 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3910 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003911 install_element (RMAP_NODE, &match_origin_cmd);
3912 install_element (RMAP_NODE, &no_match_origin_cmd);
3913 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003914 install_element (RMAP_NODE, &match_probability_cmd);
3915 install_element (RMAP_NODE, &no_match_probability_cmd);
3916 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003917
3918 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003919 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003920 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3921 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3922 install_element (RMAP_NODE, &set_local_pref_cmd);
3923 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3924 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3925 install_element (RMAP_NODE, &set_weight_cmd);
3926 install_element (RMAP_NODE, &no_set_weight_cmd);
3927 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3928 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003929 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003930 install_element (RMAP_NODE, &no_set_metric_cmd);
3931 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3932 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003933 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003934 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3935 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003936 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3937 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003938 install_element (RMAP_NODE, &set_origin_cmd);
3939 install_element (RMAP_NODE, &no_set_origin_cmd);
3940 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3941 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3942 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3943 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3944 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3945 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3946 install_element (RMAP_NODE, &set_community_cmd);
3947 install_element (RMAP_NODE, &set_community_none_cmd);
3948 install_element (RMAP_NODE, &no_set_community_cmd);
3949 install_element (RMAP_NODE, &no_set_community_val_cmd);
3950 install_element (RMAP_NODE, &no_set_community_none_cmd);
3951 install_element (RMAP_NODE, &set_community_delete_cmd);
3952 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3953 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3954 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3955 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3956 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3957 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3958 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3959 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3960 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3961 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3962 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3963 install_element (RMAP_NODE, &set_originator_id_cmd);
3964 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3965 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3966
3967#ifdef HAVE_IPV6
3968 route_map_install_match (&route_match_ipv6_address_cmd);
3969 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3970 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3971 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3972 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003973
paul718e3742002-12-13 20:15:29 +00003974 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3975 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3976 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3977 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3978 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3979 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3980 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3981 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3982 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3983 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3984 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3985 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3986#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003987
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003988 /* AS-Pathlimit: functionality removed, commands kept for
3989 * compatibility.
3990 */
Paul Jakma41367172007-08-06 15:24:51 +00003991 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3992 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3993 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3994 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3995 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3996 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003997}