blob: 4a0dac7662d091ed057fe402d81655660ac50aa9 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "prefix.h"
24#include "filter.h"
25#include "routemap.h"
26#include "command.h"
27#include "linklist.h"
28#include "plist.h"
29#include "memory.h"
30#include "log.h"
Jeremy Jackson25f45882009-01-12 16:06:12 -050031#ifdef HAVE_LIBPCREPOSIX
32# include <pcreposix.h>
paul718e3742002-12-13 20:15:29 +000033#else
Jeremy Jackson25f45882009-01-12 16:06:12 -050034# ifdef HAVE_GNU_REGEX
35# include <regex.h>
36# else
37# include "regex-gnu.h"
38# endif /* HAVE_GNU_REGEX */
39#endif /* HAVE_LIBPCREPOSIX */
paul718e3742002-12-13 20:15:29 +000040#include "buffer.h"
41#include "sockunion.h"
42
43#include "bgpd/bgpd.h"
44#include "bgpd/bgp_table.h"
45#include "bgpd/bgp_attr.h"
46#include "bgpd/bgp_aspath.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_regex.h"
49#include "bgpd/bgp_community.h"
50#include "bgpd/bgp_clist.h"
51#include "bgpd/bgp_filter.h"
52#include "bgpd/bgp_mplsvpn.h"
53#include "bgpd/bgp_ecommunity.h"
Paul Jakma320da872008-07-02 13:40:33 +000054#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000055
56/* Memo of route-map commands.
57
58o Cisco route-map
59
60 match as-path : Done
61 community : Done
62 interface : Not yet
63 ip address : Done
64 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000065 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000066 ip prefix-list : Done
67 ipv6 address : Done
68 ipv6 next-hop : Done
69 ipv6 route-source: (This will not be implemented by bgpd)
70 ipv6 prefix-list : Done
71 length : (This will not be implemented by bgpd)
72 metric : Done
73 route-type : (This will not be implemented by bgpd)
74 tag : (This will not be implemented by bgpd)
75
76 set as-path prepend : Done
77 as-path tag : Not yet
78 automatic-tag : (This will not be implemented by bgpd)
79 community : Done
80 comm-list : Not yet
81 dampning : Not yet
82 default : (This will not be implemented by bgpd)
83 interface : (This will not be implemented by bgpd)
84 ip default : (This will not be implemented by bgpd)
85 ip next-hop : Done
86 ip precedence : (This will not be implemented by bgpd)
87 ip tos : (This will not be implemented by bgpd)
88 level : (This will not be implemented by bgpd)
89 local-preference : Done
90 metric : Done
91 metric-type : Not yet
92 origin : Done
93 tag : (This will not be implemented by bgpd)
94 weight : Done
95
Timo Teräs2aa640b2014-05-20 08:57:26 +030096o Local extensions
paul718e3742002-12-13 20:15:29 +000097
98 set ipv6 next-hop global: Done
99 set ipv6 next-hop local : Done
Denis Ovsienko841f7a52008-04-10 11:47:45 +0000100 set as-path exclude : Done
paul718e3742002-12-13 20:15:29 +0000101
102*/
David Lamparter6b0655a2014-06-04 06:53:35 +0200103
Timo Teräs38f22ab2015-04-29 09:43:02 +0300104 /* generic value manipulation to be shared in multiple rules */
105
106#define RMAP_VALUE_SET 0
107#define RMAP_VALUE_ADD 1
108#define RMAP_VALUE_SUB 2
109
110struct rmap_value
111{
112 u_int8_t action;
113 u_int32_t value;
114};
115
116static int
117route_value_match (struct rmap_value *rv, u_int32_t value)
118{
119 if (value == rv->value)
120 return RMAP_MATCH;
121
122 return RMAP_NOMATCH;
123}
124
125static u_int32_t
126route_value_adjust (struct rmap_value *rv, u_int32_t current)
127{
128 u_int32_t value = rv->value;
129
130 switch (rv->action)
131 {
132 case RMAP_VALUE_ADD:
133 if (current > UINT32_MAX-value)
134 return UINT32_MAX;
135 return current + value;
136 case RMAP_VALUE_SUB:
137 if (current <= value)
138 return 0;
139 return current - value;
140 default:
141 return value;
142 }
143}
144
145static void *
146route_value_compile (const char *arg)
147{
148 u_int8_t action = RMAP_VALUE_SET;
149 unsigned long larg;
150 char *endptr = NULL;
151 struct rmap_value *rv;
152
153 if (arg[0] == '+')
154 {
155 action = RMAP_VALUE_ADD;
156 arg++;
157 }
158 else if (arg[0] == '-')
159 {
160 action = RMAP_VALUE_SUB;
161 arg++;
162 }
163
164 errno = 0;
165 larg = strtoul (arg, &endptr, 10);
166 if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
167 return NULL;
168
169 rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
170 if (!rv)
171 return NULL;
172
173 rv->action = action;
174 rv->value = larg;
175 return rv;
176}
177
178static void
179route_value_free (void *rule)
180{
181 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
182}
183
Timo Teräsb304dcb2014-05-20 09:04:49 +0300184 /* generic as path object to be shared in multiple rules */
185
186static void *
187route_aspath_compile (const char *arg)
188{
189 struct aspath *aspath;
190
191 aspath = aspath_str2aspath (arg);
192 if (! aspath)
193 return NULL;
194 return aspath;
195}
196
197static void
198route_aspath_free (void *rule)
199{
200 struct aspath *aspath = rule;
201 aspath_free (aspath);
202}
203
paulfee0f4c2004-09-13 05:12:46 +0000204 /* 'match peer (A.B.C.D|X:X::X:X)' */
205
206/* Compares the peer specified in the 'match peer' clause with the peer
207 received in bgp_info->peer. If it is the same, or if the peer structure
208 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000209static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000210route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
211 void *object)
212{
213 union sockunion *su;
David Lamparter6ed810d2015-04-21 10:13:07 +0200214 union sockunion su_def = { .sin = { .sin_family = AF_INET,
215 .sin_addr.s_addr = INADDR_ANY } };
paulfee0f4c2004-09-13 05:12:46 +0000216 struct peer_group *group;
217 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000218 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000219
220 if (type == RMAP_BGP)
221 {
222 su = rule;
223 peer = ((struct bgp_info *) object)->peer;
224
225 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
226 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
227 return RMAP_NOMATCH;
228
229 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
230 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200231 if (sockunion_same (su, &su_def))
paulfee0f4c2004-09-13 05:12:46 +0000232 {
paul22db9de2005-05-19 01:50:11 +0000233 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000234 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
235 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
236 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000237 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000238 else
paul22db9de2005-05-19 01:50:11 +0000239 ret = RMAP_NOMATCH;
paul22db9de2005-05-19 01:50:11 +0000240 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000241 }
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200242
paulfee0f4c2004-09-13 05:12:46 +0000243 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
244 {
245 if (sockunion_same (su, &peer->su))
246 return RMAP_MATCH;
247
248 return RMAP_NOMATCH;
249 }
250 else
251 {
252 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000253 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000254 {
255 if (sockunion_same (su, &peer->su))
256 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000257 }
Paul Jakma30a22312008-08-15 14:05:22 +0100258 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000259 }
260 }
261 return RMAP_NOMATCH;
262}
263
paul94f2b392005-06-28 12:44:16 +0000264static void *
paulfd79ac92004-10-13 05:06:08 +0000265route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000266{
267 union sockunion *su;
268 int ret;
269
270 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
271
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +0200272 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
paulfee0f4c2004-09-13 05:12:46 +0000273 if (ret < 0) {
274 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
275 return NULL;
276 }
277
278 return su;
279}
280
281/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000282static void
paulfee0f4c2004-09-13 05:12:46 +0000283route_match_peer_free (void *rule)
284{
285 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
286}
287
288/* Route map commands for ip address matching. */
289struct route_map_rule_cmd route_match_peer_cmd =
290{
291 "peer",
292 route_match_peer,
293 route_match_peer_compile,
294 route_match_peer_free
295};
296
paul718e3742002-12-13 20:15:29 +0000297/* `match ip address IP_ACCESS_LIST' */
298
299/* Match function should return 1 if match is success else return
300 zero. */
paul94f2b392005-06-28 12:44:16 +0000301static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000302route_match_ip_address (void *rule, struct prefix *prefix,
303 route_map_object_t type, void *object)
304{
305 struct access_list *alist;
306 /* struct prefix_ipv4 match; */
307
308 if (type == RMAP_BGP)
309 {
310 alist = access_list_lookup (AFI_IP, (char *) rule);
311 if (alist == NULL)
312 return RMAP_NOMATCH;
313
314 return (access_list_apply (alist, prefix) == FILTER_DENY ?
315 RMAP_NOMATCH : RMAP_MATCH);
316 }
317 return RMAP_NOMATCH;
318}
319
320/* Route map `ip address' match statement. `arg' should be
321 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000322static void *
paulfd79ac92004-10-13 05:06:08 +0000323route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000324{
325 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
326}
327
328/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000329static void
paul718e3742002-12-13 20:15:29 +0000330route_match_ip_address_free (void *rule)
331{
332 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
333}
334
335/* Route map commands for ip address matching. */
336struct route_map_rule_cmd route_match_ip_address_cmd =
337{
338 "ip address",
339 route_match_ip_address,
340 route_match_ip_address_compile,
341 route_match_ip_address_free
342};
David Lamparter6b0655a2014-06-04 06:53:35 +0200343
paul718e3742002-12-13 20:15:29 +0000344/* `match ip next-hop IP_ADDRESS' */
345
346/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000347static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000348route_match_ip_next_hop (void *rule, struct prefix *prefix,
349 route_map_object_t type, void *object)
350{
351 struct access_list *alist;
352 struct bgp_info *bgp_info;
353 struct prefix_ipv4 p;
354
355 if (type == RMAP_BGP)
356 {
357 bgp_info = object;
358 p.family = AF_INET;
359 p.prefix = bgp_info->attr->nexthop;
360 p.prefixlen = IPV4_MAX_BITLEN;
361
362 alist = access_list_lookup (AFI_IP, (char *) rule);
363 if (alist == NULL)
364 return RMAP_NOMATCH;
365
366 return (access_list_apply (alist, &p) == FILTER_DENY ?
367 RMAP_NOMATCH : RMAP_MATCH);
368 }
369 return RMAP_NOMATCH;
370}
371
372/* Route map `ip next-hop' match statement. `arg' is
373 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000374static void *
paulfd79ac92004-10-13 05:06:08 +0000375route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000376{
377 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
378}
379
380/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000381static void
paul718e3742002-12-13 20:15:29 +0000382route_match_ip_next_hop_free (void *rule)
383{
384 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
385}
386
387/* Route map commands for ip next-hop matching. */
388struct route_map_rule_cmd route_match_ip_next_hop_cmd =
389{
390 "ip next-hop",
391 route_match_ip_next_hop,
392 route_match_ip_next_hop_compile,
393 route_match_ip_next_hop_free
394};
David Lamparter6b0655a2014-06-04 06:53:35 +0200395
hassoc1643bb2005-02-02 16:43:17 +0000396/* `match ip route-source ACCESS-LIST' */
397
398/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000399static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000400route_match_ip_route_source (void *rule, struct prefix *prefix,
401 route_map_object_t type, void *object)
402{
403 struct access_list *alist;
404 struct bgp_info *bgp_info;
405 struct peer *peer;
406 struct prefix_ipv4 p;
407
408 if (type == RMAP_BGP)
409 {
410 bgp_info = object;
411 peer = bgp_info->peer;
412
413 if (! peer || sockunion_family (&peer->su) != AF_INET)
414 return RMAP_NOMATCH;
415
416 p.family = AF_INET;
417 p.prefix = peer->su.sin.sin_addr;
418 p.prefixlen = IPV4_MAX_BITLEN;
419
420 alist = access_list_lookup (AFI_IP, (char *) rule);
421 if (alist == NULL)
422 return RMAP_NOMATCH;
423
424 return (access_list_apply (alist, &p) == FILTER_DENY ?
425 RMAP_NOMATCH : RMAP_MATCH);
426 }
427 return RMAP_NOMATCH;
428}
429
430/* Route map `ip route-source' match statement. `arg' is
431 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000432static void *
hassoc1643bb2005-02-02 16:43:17 +0000433route_match_ip_route_source_compile (const char *arg)
434{
435 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
436}
437
438/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000439static void
hassoc1643bb2005-02-02 16:43:17 +0000440route_match_ip_route_source_free (void *rule)
441{
442 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
443}
444
445/* Route map commands for ip route-source matching. */
446struct route_map_rule_cmd route_match_ip_route_source_cmd =
447{
448 "ip route-source",
449 route_match_ip_route_source,
450 route_match_ip_route_source_compile,
451 route_match_ip_route_source_free
452};
David Lamparter6b0655a2014-06-04 06:53:35 +0200453
paul718e3742002-12-13 20:15:29 +0000454/* `match ip address prefix-list PREFIX_LIST' */
455
paul94f2b392005-06-28 12:44:16 +0000456static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000457route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
458 route_map_object_t type, void *object)
459{
460 struct prefix_list *plist;
461
462 if (type == RMAP_BGP)
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, prefix) == PREFIX_DENY ?
469 RMAP_NOMATCH : RMAP_MATCH);
470 }
471 return RMAP_NOMATCH;
472}
473
paul94f2b392005-06-28 12:44:16 +0000474static void *
paulfd79ac92004-10-13 05:06:08 +0000475route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000476{
477 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
478}
479
paul94f2b392005-06-28 12:44:16 +0000480static void
paul718e3742002-12-13 20:15:29 +0000481route_match_ip_address_prefix_list_free (void *rule)
482{
483 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
484}
485
486struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
487{
488 "ip address prefix-list",
489 route_match_ip_address_prefix_list,
490 route_match_ip_address_prefix_list_compile,
491 route_match_ip_address_prefix_list_free
492};
David Lamparter6b0655a2014-06-04 06:53:35 +0200493
paul718e3742002-12-13 20:15:29 +0000494/* `match ip next-hop prefix-list PREFIX_LIST' */
495
paul94f2b392005-06-28 12:44:16 +0000496static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000497route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
498 route_map_object_t type, void *object)
499{
500 struct prefix_list *plist;
501 struct bgp_info *bgp_info;
502 struct prefix_ipv4 p;
503
504 if (type == RMAP_BGP)
505 {
506 bgp_info = object;
507 p.family = AF_INET;
508 p.prefix = bgp_info->attr->nexthop;
509 p.prefixlen = IPV4_MAX_BITLEN;
510
511 plist = prefix_list_lookup (AFI_IP, (char *) rule);
512 if (plist == NULL)
513 return RMAP_NOMATCH;
514
515 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
516 RMAP_NOMATCH : RMAP_MATCH);
517 }
518 return RMAP_NOMATCH;
519}
520
paul94f2b392005-06-28 12:44:16 +0000521static void *
paulfd79ac92004-10-13 05:06:08 +0000522route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000523{
524 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
525}
526
paul94f2b392005-06-28 12:44:16 +0000527static void
paul718e3742002-12-13 20:15:29 +0000528route_match_ip_next_hop_prefix_list_free (void *rule)
529{
530 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
531}
532
533struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
534{
535 "ip next-hop prefix-list",
536 route_match_ip_next_hop_prefix_list,
537 route_match_ip_next_hop_prefix_list_compile,
538 route_match_ip_next_hop_prefix_list_free
539};
David Lamparter6b0655a2014-06-04 06:53:35 +0200540
hassoc1643bb2005-02-02 16:43:17 +0000541/* `match ip route-source prefix-list PREFIX_LIST' */
542
paul94f2b392005-06-28 12:44:16 +0000543static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000544route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
545 route_map_object_t type, void *object)
546{
547 struct prefix_list *plist;
548 struct bgp_info *bgp_info;
549 struct peer *peer;
550 struct prefix_ipv4 p;
551
552 if (type == RMAP_BGP)
553 {
554 bgp_info = object;
555 peer = bgp_info->peer;
556
557 if (! peer || sockunion_family (&peer->su) != AF_INET)
558 return RMAP_NOMATCH;
559
560 p.family = AF_INET;
561 p.prefix = peer->su.sin.sin_addr;
562 p.prefixlen = IPV4_MAX_BITLEN;
563
564 plist = prefix_list_lookup (AFI_IP, (char *) rule);
565 if (plist == NULL)
566 return RMAP_NOMATCH;
567
568 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
569 RMAP_NOMATCH : RMAP_MATCH);
570 }
571 return RMAP_NOMATCH;
572}
573
paul94f2b392005-06-28 12:44:16 +0000574static void *
hassoc1643bb2005-02-02 16:43:17 +0000575route_match_ip_route_source_prefix_list_compile (const char *arg)
576{
577 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
578}
579
paul94f2b392005-06-28 12:44:16 +0000580static void
hassoc1643bb2005-02-02 16:43:17 +0000581route_match_ip_route_source_prefix_list_free (void *rule)
582{
583 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
584}
585
586struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
587{
588 "ip route-source prefix-list",
589 route_match_ip_route_source_prefix_list,
590 route_match_ip_route_source_prefix_list_compile,
591 route_match_ip_route_source_prefix_list_free
592};
David Lamparter6b0655a2014-06-04 06:53:35 +0200593
paul718e3742002-12-13 20:15:29 +0000594/* `match metric METRIC' */
595
596/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000597static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000598route_match_metric (void *rule, struct prefix *prefix,
599 route_map_object_t type, void *object)
600{
Timo Teräs38f22ab2015-04-29 09:43:02 +0300601 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +0000602 struct bgp_info *bgp_info;
603
604 if (type == RMAP_BGP)
605 {
Timo Teräs38f22ab2015-04-29 09:43:02 +0300606 rv = rule;
paul718e3742002-12-13 20:15:29 +0000607 bgp_info = object;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300608 return route_value_match(rv, bgp_info->attr->med);
paul718e3742002-12-13 20:15:29 +0000609 }
610 return RMAP_NOMATCH;
611}
612
paul718e3742002-12-13 20:15:29 +0000613/* Route map commands for metric matching. */
614struct route_map_rule_cmd route_match_metric_cmd =
615{
616 "metric",
617 route_match_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +0300618 route_value_compile,
619 route_value_free,
paul718e3742002-12-13 20:15:29 +0000620};
David Lamparter6b0655a2014-06-04 06:53:35 +0200621
paul718e3742002-12-13 20:15:29 +0000622/* `match as-path ASPATH' */
623
624/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000625static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000626route_match_aspath (void *rule, struct prefix *prefix,
627 route_map_object_t type, void *object)
628{
629
630 struct as_list *as_list;
631 struct bgp_info *bgp_info;
632
633 if (type == RMAP_BGP)
634 {
635 as_list = as_list_lookup ((char *) rule);
636 if (as_list == NULL)
637 return RMAP_NOMATCH;
638
639 bgp_info = object;
640
641 /* Perform match. */
642 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
643 }
644 return RMAP_NOMATCH;
645}
646
647/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000648static void *
paulfd79ac92004-10-13 05:06:08 +0000649route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000650{
651 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
652}
653
654/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000655static void
paul718e3742002-12-13 20:15:29 +0000656route_match_aspath_free (void *rule)
657{
658 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
659}
660
661/* Route map commands for aspath matching. */
662struct route_map_rule_cmd route_match_aspath_cmd =
663{
664 "as-path",
665 route_match_aspath,
666 route_match_aspath_compile,
667 route_match_aspath_free
668};
David Lamparter6b0655a2014-06-04 06:53:35 +0200669
paul718e3742002-12-13 20:15:29 +0000670/* `match community COMMUNIY' */
671struct rmap_community
672{
673 char *name;
674 int exact;
675};
676
677/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000678static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000679route_match_community (void *rule, struct prefix *prefix,
680 route_map_object_t type, void *object)
681{
682 struct community_list *list;
683 struct bgp_info *bgp_info;
684 struct rmap_community *rcom;
685
686 if (type == RMAP_BGP)
687 {
688 bgp_info = object;
689 rcom = rule;
690
hassofee6e4e2005-02-02 16:29:31 +0000691 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000692 if (! list)
693 return RMAP_NOMATCH;
694
695 if (rcom->exact)
696 {
697 if (community_list_exact_match (bgp_info->attr->community, list))
698 return RMAP_MATCH;
699 }
700 else
701 {
702 if (community_list_match (bgp_info->attr->community, list))
703 return RMAP_MATCH;
704 }
705 }
706 return RMAP_NOMATCH;
707}
708
709/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000710static void *
paulfd79ac92004-10-13 05:06:08 +0000711route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000712{
713 struct rmap_community *rcom;
714 int len;
715 char *p;
716
717 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
718
719 p = strchr (arg, ' ');
720 if (p)
721 {
722 len = p - arg;
723 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
724 memcpy (rcom->name, arg, len);
725 rcom->exact = 1;
726 }
727 else
728 {
729 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
730 rcom->exact = 0;
731 }
732 return rcom;
733}
734
735/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000736static void
paul718e3742002-12-13 20:15:29 +0000737route_match_community_free (void *rule)
738{
739 struct rmap_community *rcom = rule;
740
741 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
742 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
743}
744
745/* Route map commands for community matching. */
746struct route_map_rule_cmd route_match_community_cmd =
747{
748 "community",
749 route_match_community,
750 route_match_community_compile,
751 route_match_community_free
752};
David Lamparter6b0655a2014-06-04 06:53:35 +0200753
paul73ffb252003-04-19 15:49:49 +0000754/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000755static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000756route_match_ecommunity (void *rule, struct prefix *prefix,
757 route_map_object_t type, void *object)
758{
759 struct community_list *list;
760 struct bgp_info *bgp_info;
761
762 if (type == RMAP_BGP)
763 {
764 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000765
766 if (!bgp_info->attr->extra)
767 return RMAP_NOMATCH;
768
paul73ffb252003-04-19 15:49:49 +0000769 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000770 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000771 if (! list)
772 return RMAP_NOMATCH;
773
Paul Jakmafb982c22007-05-04 20:15:47 +0000774 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000775 return RMAP_MATCH;
776 }
777 return RMAP_NOMATCH;
778}
779
780/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000781static void *
paulfd79ac92004-10-13 05:06:08 +0000782route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000783{
784 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
785}
786
787/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000788static void
paul73ffb252003-04-19 15:49:49 +0000789route_match_ecommunity_free (void *rule)
790{
791 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
792}
793
794/* Route map commands for community matching. */
795struct route_map_rule_cmd route_match_ecommunity_cmd =
796{
797 "extcommunity",
798 route_match_ecommunity,
799 route_match_ecommunity_compile,
800 route_match_ecommunity_free
801};
David Lamparter6b0655a2014-06-04 06:53:35 +0200802
paul718e3742002-12-13 20:15:29 +0000803/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
804 and `address-family vpnv4'. */
David Lamparter6b0655a2014-06-04 06:53:35 +0200805
paul718e3742002-12-13 20:15:29 +0000806/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000807static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000808route_match_origin (void *rule, struct prefix *prefix,
809 route_map_object_t type, void *object)
810{
811 u_char *origin;
812 struct bgp_info *bgp_info;
813
814 if (type == RMAP_BGP)
815 {
816 origin = rule;
817 bgp_info = object;
818
819 if (bgp_info->attr->origin == *origin)
820 return RMAP_MATCH;
821 }
822
823 return RMAP_NOMATCH;
824}
825
paul94f2b392005-06-28 12:44:16 +0000826static void *
paulfd79ac92004-10-13 05:06:08 +0000827route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000828{
829 u_char *origin;
830
831 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
832
833 if (strcmp (arg, "igp") == 0)
834 *origin = 0;
835 else if (strcmp (arg, "egp") == 0)
836 *origin = 1;
837 else
838 *origin = 2;
839
840 return origin;
841}
842
843/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000844static void
paul718e3742002-12-13 20:15:29 +0000845route_match_origin_free (void *rule)
846{
847 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
848}
849
850/* Route map commands for origin matching. */
851struct route_map_rule_cmd route_match_origin_cmd =
852{
853 "origin",
854 route_match_origin,
855 route_match_origin_compile,
856 route_match_origin_free
857};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400858
859/* match probability { */
860
861static route_map_result_t
862route_match_probability (void *rule, struct prefix *prefix,
863 route_map_object_t type, void *object)
864{
865 long r;
866#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
867 r = random();
868#else
869 r = (long) rand();
870#endif
871
David Lamparter8c9cd852015-04-19 14:40:02 +0200872 switch (*(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400873 {
874 case 0: break;
875 case RAND_MAX: return RMAP_MATCH;
876 default:
David Lamparter8c9cd852015-04-19 14:40:02 +0200877 if (r < *(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400878 {
879 return RMAP_MATCH;
880 }
881 }
882
883 return RMAP_NOMATCH;
884}
885
886static void *
887route_match_probability_compile (const char *arg)
888{
David Lamparter8c9cd852015-04-19 14:40:02 +0200889 long *lobule;
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400890 unsigned perc;
891
892#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
893 srandom (time (NULL));
894#else
895 srand (time (NULL));
896#endif
897
898 perc = atoi (arg);
David Lamparter8c9cd852015-04-19 14:40:02 +0200899 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400900
901 switch (perc)
902 {
903 case 0: *lobule = 0; break;
904 case 100: *lobule = RAND_MAX; break;
905 default: *lobule = RAND_MAX / 100 * perc;
906 }
907
908 return lobule;
909}
910
911static void
912route_match_probability_free (void *rule)
913{
914 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
915}
916
917struct route_map_rule_cmd route_match_probability_cmd =
918{
919 "probability",
920 route_match_probability,
921 route_match_probability_compile,
922 route_match_probability_free
923};
924
925/* } */
926
paul718e3742002-12-13 20:15:29 +0000927/* `set ip next-hop IP_ADDRESS' */
928
929/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000930struct rmap_ip_nexthop_set
931{
932 struct in_addr *address;
933 int peer_address;
934};
935
paul94f2b392005-06-28 12:44:16 +0000936static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000937route_set_ip_nexthop (void *rule, struct prefix *prefix,
938 route_map_object_t type, void *object)
939{
paulac41b2a2003-08-12 05:32:27 +0000940 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +0000941 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000942 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000943
944 if (type == RMAP_BGP)
945 {
paul718e3742002-12-13 20:15:29 +0000946 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000947 peer = bgp_info->peer;
948
949 if (rins->peer_address)
950 {
paulfee0f4c2004-09-13 05:12:46 +0000951 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
952 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000953 && peer->su_remote
954 && sockunion_family (peer->su_remote) == AF_INET)
955 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200956 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +0000957 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
958 }
959 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
960 && peer->su_local
961 && sockunion_family (peer->su_local) == AF_INET)
962 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200963 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +0000964 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
965 }
966 }
967 else
968 {
969 /* Set next hop value. */
970 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
971 bgp_info->attr->nexthop = *rins->address;
972 }
paul718e3742002-12-13 20:15:29 +0000973 }
974
975 return RMAP_OKAY;
976}
977
978/* Route map `ip nexthop' compile function. Given string is converted
979 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000980static void *
paulfd79ac92004-10-13 05:06:08 +0000981route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000982{
paulac41b2a2003-08-12 05:32:27 +0000983 struct rmap_ip_nexthop_set *rins;
984 struct in_addr *address = NULL;
985 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000986 int ret;
paul718e3742002-12-13 20:15:29 +0000987
paulac41b2a2003-08-12 05:32:27 +0000988 if (strcmp (arg, "peer-address") == 0)
989 peer_address = 1;
990 else
paul718e3742002-12-13 20:15:29 +0000991 {
paulac41b2a2003-08-12 05:32:27 +0000992 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
993 ret = inet_aton (arg, address);
994
995 if (ret == 0)
996 {
997 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
998 return NULL;
999 }
paul718e3742002-12-13 20:15:29 +00001000 }
1001
Stephen Hemminger393deb92008-08-18 14:13:29 -07001002 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +00001003
1004 rins->address = address;
1005 rins->peer_address = peer_address;
1006
1007 return rins;
paul718e3742002-12-13 20:15:29 +00001008}
1009
1010/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001011static void
paul718e3742002-12-13 20:15:29 +00001012route_set_ip_nexthop_free (void *rule)
1013{
paulac41b2a2003-08-12 05:32:27 +00001014 struct rmap_ip_nexthop_set *rins = rule;
1015
1016 if (rins->address)
1017 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1018
1019 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +00001020}
1021
1022/* Route map commands for ip nexthop set. */
1023struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1024{
1025 "ip next-hop",
1026 route_set_ip_nexthop,
1027 route_set_ip_nexthop_compile,
1028 route_set_ip_nexthop_free
1029};
David Lamparter6b0655a2014-06-04 06:53:35 +02001030
paul718e3742002-12-13 20:15:29 +00001031/* `set local-preference LOCAL_PREF' */
1032
1033/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +00001034static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001035route_set_local_pref (void *rule, struct prefix *prefix,
1036 route_map_object_t type, void *object)
1037{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001038 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001039 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001040 u_int32_t locpref = 0;
paul718e3742002-12-13 20:15:29 +00001041
1042 if (type == RMAP_BGP)
1043 {
1044 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001045 rv = rule;
paul718e3742002-12-13 20:15:29 +00001046 bgp_info = object;
1047
1048 /* Set local preference value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001049 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1050 locpref = bgp_info->attr->local_pref;
1051
paul718e3742002-12-13 20:15:29 +00001052 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
Timo Teräs38f22ab2015-04-29 09:43:02 +03001053 bgp_info->attr->local_pref = route_value_adjust(rv, locpref);
paul718e3742002-12-13 20:15:29 +00001054 }
1055
1056 return RMAP_OKAY;
1057}
1058
paul718e3742002-12-13 20:15:29 +00001059/* Set local preference rule structure. */
1060struct route_map_rule_cmd route_set_local_pref_cmd =
1061{
1062 "local-preference",
1063 route_set_local_pref,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001064 route_value_compile,
1065 route_value_free,
paul718e3742002-12-13 20:15:29 +00001066};
David Lamparter6b0655a2014-06-04 06:53:35 +02001067
paul718e3742002-12-13 20:15:29 +00001068/* `set weight WEIGHT' */
1069
1070/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001071static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001072route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1073 void *object)
1074{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001075 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001076 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001077 u_int32_t weight;
paul718e3742002-12-13 20:15:29 +00001078
1079 if (type == RMAP_BGP)
1080 {
1081 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001082 rv = rule;
paul718e3742002-12-13 20:15:29 +00001083 bgp_info = object;
1084
1085 /* Set weight value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001086 weight = route_value_adjust(rv, 0);
1087 if (weight)
1088 (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
Paul Jakmafb982c22007-05-04 20:15:47 +00001089 else if (bgp_info->attr->extra)
1090 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001091 }
1092
1093 return RMAP_OKAY;
1094}
1095
paul718e3742002-12-13 20:15:29 +00001096/* Set local preference rule structure. */
1097struct route_map_rule_cmd route_set_weight_cmd =
1098{
1099 "weight",
1100 route_set_weight,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001101 route_value_compile,
1102 route_value_free,
paul718e3742002-12-13 20:15:29 +00001103};
David Lamparter6b0655a2014-06-04 06:53:35 +02001104
paul718e3742002-12-13 20:15:29 +00001105/* `set metric METRIC' */
1106
1107/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001108static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001109route_set_metric (void *rule, struct prefix *prefix,
1110 route_map_object_t type, void *object)
1111{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001112 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001113 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001114 u_int32_t med = 0;
paul718e3742002-12-13 20:15:29 +00001115
1116 if (type == RMAP_BGP)
1117 {
1118 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001119 rv = rule;
paul718e3742002-12-13 20:15:29 +00001120 bgp_info = object;
1121
Timo Teräs38f22ab2015-04-29 09:43:02 +03001122 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1123 med = bgp_info->attr->med;
1124
1125 bgp_info->attr->med = route_value_adjust(rv, med);
paul718e3742002-12-13 20:15:29 +00001126 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
paul718e3742002-12-13 20:15:29 +00001127 }
1128 return RMAP_OKAY;
1129}
1130
paul718e3742002-12-13 20:15:29 +00001131/* Set metric rule structure. */
1132struct route_map_rule_cmd route_set_metric_cmd =
1133{
1134 "metric",
1135 route_set_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001136 route_value_compile,
1137 route_value_free,
paul718e3742002-12-13 20:15:29 +00001138};
David Lamparter6b0655a2014-06-04 06:53:35 +02001139
paul718e3742002-12-13 20:15:29 +00001140/* `set as-path prepend ASPATH' */
1141
1142/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001143static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001144route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1145{
1146 struct aspath *aspath;
1147 struct aspath *new;
1148 struct bgp_info *binfo;
1149
1150 if (type == RMAP_BGP)
1151 {
paul718e3742002-12-13 20:15:29 +00001152 binfo = object;
1153
1154 if (binfo->attr->aspath->refcnt)
1155 new = aspath_dup (binfo->attr->aspath);
1156 else
1157 new = binfo->attr->aspath;
1158
Timo Teräs85c854a2014-09-30 11:31:53 +03001159 if ((uintptr_t)rule > 10)
1160 {
1161 aspath = rule;
1162 aspath_prepend (aspath, new);
1163 }
1164 else
1165 {
1166 as_t as = aspath_leftmost(new);
1167 if (!as) as = binfo->peer->as;
1168 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1169 }
1170
paul718e3742002-12-13 20:15:29 +00001171 binfo->attr->aspath = new;
1172 }
1173
1174 return RMAP_OKAY;
1175}
1176
Timo Teräs85c854a2014-09-30 11:31:53 +03001177static void *
1178route_set_aspath_prepend_compile (const char *arg)
1179{
1180 unsigned int num;
1181
1182 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1183 return (void*)(uintptr_t)num;
1184
1185 return route_aspath_compile(arg);
1186}
1187
1188static void
1189route_set_aspath_prepend_free (void *rule)
1190{
1191 if ((uintptr_t)rule > 10)
1192 route_aspath_free(rule);
1193}
1194
1195
Timo Teräs2aa640b2014-05-20 08:57:26 +03001196/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001197struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1198{
1199 "as-path prepend",
1200 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001201 route_set_aspath_prepend_compile,
1202 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001203};
David Lamparter6b0655a2014-06-04 06:53:35 +02001204
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001205/* `set as-path exclude ASn' */
1206
1207/* For ASN exclude mechanism.
1208 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1209 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1210 */
1211static route_map_result_t
1212route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1213{
1214 struct aspath * new_path, * exclude_path;
1215 struct bgp_info *binfo;
1216
1217 if (type == RMAP_BGP)
1218 {
1219 exclude_path = rule;
1220 binfo = object;
1221 if (binfo->attr->aspath->refcnt)
1222 new_path = aspath_dup (binfo->attr->aspath);
1223 else
1224 new_path = binfo->attr->aspath;
1225 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1226 }
1227 return RMAP_OKAY;
1228}
1229
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001230/* Set ASn exlude rule structure. */
1231struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1232{
1233 "as-path exclude",
1234 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001235 route_aspath_compile,
1236 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001237};
David Lamparter6b0655a2014-06-04 06:53:35 +02001238
paul718e3742002-12-13 20:15:29 +00001239/* `set community COMMUNITY' */
1240struct rmap_com_set
1241{
1242 struct community *com;
1243 int additive;
1244 int none;
1245};
1246
1247/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001248static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001249route_set_community (void *rule, struct prefix *prefix,
1250 route_map_object_t type, void *object)
1251{
1252 struct rmap_com_set *rcs;
1253 struct bgp_info *binfo;
1254 struct attr *attr;
1255 struct community *new = NULL;
1256 struct community *old;
1257 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001258
paul718e3742002-12-13 20:15:29 +00001259 if (type == RMAP_BGP)
1260 {
1261 rcs = rule;
1262 binfo = object;
1263 attr = binfo->attr;
1264 old = attr->community;
1265
1266 /* "none" case. */
1267 if (rcs->none)
1268 {
1269 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1270 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001271 /* See the longer comment down below. */
1272 if (old && old->refcnt == 0)
1273 community_free(old);
paul718e3742002-12-13 20:15:29 +00001274 return RMAP_OKAY;
1275 }
1276
1277 /* "additive" case. */
1278 if (rcs->additive && old)
1279 {
1280 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001281
1282 /* HACK: if the old community is not intern'd,
1283 * we should free it here, or all reference to it may be lost.
1284 * Really need to cleanup attribute caching sometime.
1285 */
1286 if (old->refcnt == 0)
1287 community_free (old);
paul718e3742002-12-13 20:15:29 +00001288 new = community_uniq_sort (merge);
1289 community_free (merge);
1290 }
1291 else
1292 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001293
1294 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001295 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001296
paul718e3742002-12-13 20:15:29 +00001297 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1298 }
1299
1300 return RMAP_OKAY;
1301}
1302
1303/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001304static void *
paulfd79ac92004-10-13 05:06:08 +00001305route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001306{
1307 struct rmap_com_set *rcs;
1308 struct community *com = NULL;
1309 char *sp;
1310 int additive = 0;
1311 int none = 0;
1312
1313 if (strcmp (arg, "none") == 0)
1314 none = 1;
1315 else
1316 {
1317 sp = strstr (arg, "additive");
1318
1319 if (sp && sp > arg)
1320 {
1321 /* "additive" keyworkd is included. */
1322 additive = 1;
1323 *(sp - 1) = '\0';
1324 }
1325
1326 com = community_str2com (arg);
1327
1328 if (additive)
1329 *(sp - 1) = ' ';
1330
1331 if (! com)
1332 return NULL;
1333 }
1334
Stephen Hemminger393deb92008-08-18 14:13:29 -07001335 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001336 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001337 rcs->additive = additive;
1338 rcs->none = none;
1339
1340 return rcs;
1341}
1342
1343/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001344static void
paul718e3742002-12-13 20:15:29 +00001345route_set_community_free (void *rule)
1346{
1347 struct rmap_com_set *rcs = rule;
1348
1349 if (rcs->com)
1350 community_free (rcs->com);
1351 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1352}
1353
1354/* Set community rule structure. */
1355struct route_map_rule_cmd route_set_community_cmd =
1356{
1357 "community",
1358 route_set_community,
1359 route_set_community_compile,
1360 route_set_community_free,
1361};
David Lamparter6b0655a2014-06-04 06:53:35 +02001362
hassofee6e4e2005-02-02 16:29:31 +00001363/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001364
1365/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001366static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001367route_set_community_delete (void *rule, struct prefix *prefix,
1368 route_map_object_t type, void *object)
1369{
1370 struct community_list *list;
1371 struct community *merge;
1372 struct community *new;
1373 struct community *old;
1374 struct bgp_info *binfo;
1375
1376 if (type == RMAP_BGP)
1377 {
1378 if (! rule)
1379 return RMAP_OKAY;
1380
1381 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001382 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001383 old = binfo->attr->community;
1384
1385 if (list && old)
1386 {
1387 merge = community_list_match_delete (community_dup (old), list);
1388 new = community_uniq_sort (merge);
1389 community_free (merge);
1390
Michael Lambert604a9b42010-09-13 11:48:11 -04001391 /* HACK: if the old community is not intern'd,
1392 * we should free it here, or all reference to it may be lost.
1393 * Really need to cleanup attribute caching sometime.
1394 */
1395 if (old->refcnt == 0)
1396 community_free (old);
1397
paul718e3742002-12-13 20:15:29 +00001398 if (new->size == 0)
1399 {
1400 binfo->attr->community = NULL;
1401 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1402 community_free (new);
1403 }
1404 else
1405 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001406 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001407 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1408 }
1409 }
1410 }
1411
1412 return RMAP_OKAY;
1413}
1414
1415/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001416static void *
paulfd79ac92004-10-13 05:06:08 +00001417route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001418{
1419 char *p;
1420 char *str;
1421 int len;
1422
1423 p = strchr (arg, ' ');
1424 if (p)
1425 {
1426 len = p - arg;
1427 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1428 memcpy (str, arg, len);
1429 }
1430 else
1431 str = NULL;
1432
1433 return str;
1434}
1435
1436/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001437static void
paul718e3742002-12-13 20:15:29 +00001438route_set_community_delete_free (void *rule)
1439{
1440 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1441}
1442
1443/* Set community rule structure. */
1444struct route_map_rule_cmd route_set_community_delete_cmd =
1445{
1446 "comm-list",
1447 route_set_community_delete,
1448 route_set_community_delete_compile,
1449 route_set_community_delete_free,
1450};
David Lamparter6b0655a2014-06-04 06:53:35 +02001451
paul718e3742002-12-13 20:15:29 +00001452/* `set extcommunity rt COMMUNITY' */
1453
David Lamparter73d78ea2014-06-04 00:58:47 +02001454/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001455static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001456route_set_ecommunity (void *rule, struct prefix *prefix,
1457 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001458{
1459 struct ecommunity *ecom;
1460 struct ecommunity *new_ecom;
1461 struct ecommunity *old_ecom;
1462 struct bgp_info *bgp_info;
1463
1464 if (type == RMAP_BGP)
1465 {
1466 ecom = rule;
1467 bgp_info = object;
1468
1469 if (! ecom)
1470 return RMAP_OKAY;
1471
1472 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001473 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001474
1475 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001476 {
1477 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1478
1479 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1480 * ->refcnt = 0 => set by a previous route-map statement */
1481 if (!old_ecom->refcnt)
1482 ecommunity_free (&old_ecom);
1483 }
paul718e3742002-12-13 20:15:29 +00001484 else
1485 new_ecom = ecommunity_dup (ecom);
1486
David Lamparter27bf90a2014-06-04 00:59:01 +02001487 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1488 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001489
paul718e3742002-12-13 20:15:29 +00001490 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1491 }
1492 return RMAP_OKAY;
1493}
1494
1495/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001496static void *
paulfd79ac92004-10-13 05:06:08 +00001497route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001498{
1499 struct ecommunity *ecom;
1500
1501 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1502 if (! ecom)
1503 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001504 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001505}
1506
David Lamparter73d78ea2014-06-04 00:58:47 +02001507/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001508static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001509route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001510{
1511 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001512 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001513}
1514
1515/* Set community rule structure. */
1516struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1517{
1518 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001519 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001520 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001521 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001522};
1523
1524/* `set extcommunity soo COMMUNITY' */
1525
paul718e3742002-12-13 20:15:29 +00001526/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001527static void *
paulfd79ac92004-10-13 05:06:08 +00001528route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001529{
1530 struct ecommunity *ecom;
1531
1532 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1533 if (! ecom)
1534 return NULL;
1535
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001536 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001537}
1538
paul718e3742002-12-13 20:15:29 +00001539/* Set community rule structure. */
1540struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1541{
1542 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001543 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001544 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001545 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001546};
David Lamparter6b0655a2014-06-04 06:53:35 +02001547
paul718e3742002-12-13 20:15:29 +00001548/* `set origin ORIGIN' */
1549
1550/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001551static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001552route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1553{
1554 u_char *origin;
1555 struct bgp_info *bgp_info;
1556
1557 if (type == RMAP_BGP)
1558 {
1559 origin = rule;
1560 bgp_info = object;
1561
1562 bgp_info->attr->origin = *origin;
1563 }
1564
1565 return RMAP_OKAY;
1566}
1567
1568/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001569static void *
paulfd79ac92004-10-13 05:06:08 +00001570route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001571{
1572 u_char *origin;
1573
1574 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1575
1576 if (strcmp (arg, "igp") == 0)
1577 *origin = 0;
1578 else if (strcmp (arg, "egp") == 0)
1579 *origin = 1;
1580 else
1581 *origin = 2;
1582
1583 return origin;
1584}
1585
1586/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001587static void
paul718e3742002-12-13 20:15:29 +00001588route_set_origin_free (void *rule)
1589{
1590 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1591}
1592
Timo Teräs2aa640b2014-05-20 08:57:26 +03001593/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001594struct route_map_rule_cmd route_set_origin_cmd =
1595{
1596 "origin",
1597 route_set_origin,
1598 route_set_origin_compile,
1599 route_set_origin_free,
1600};
David Lamparter6b0655a2014-06-04 06:53:35 +02001601
paul718e3742002-12-13 20:15:29 +00001602/* `set atomic-aggregate' */
1603
1604/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001605static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001606route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1607 route_map_object_t type, void *object)
1608{
1609 struct bgp_info *bgp_info;
1610
1611 if (type == RMAP_BGP)
1612 {
1613 bgp_info = object;
1614 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1615 }
1616
1617 return RMAP_OKAY;
1618}
1619
1620/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001621static void *
paulfd79ac92004-10-13 05:06:08 +00001622route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001623{
1624 return (void *)1;
1625}
1626
1627/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001628static void
paul718e3742002-12-13 20:15:29 +00001629route_set_atomic_aggregate_free (void *rule)
1630{
1631 return;
1632}
1633
1634/* Set atomic aggregate rule structure. */
1635struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1636{
1637 "atomic-aggregate",
1638 route_set_atomic_aggregate,
1639 route_set_atomic_aggregate_compile,
1640 route_set_atomic_aggregate_free,
1641};
David Lamparter6b0655a2014-06-04 06:53:35 +02001642
paul718e3742002-12-13 20:15:29 +00001643/* `set aggregator as AS A.B.C.D' */
1644struct aggregator
1645{
1646 as_t as;
1647 struct in_addr address;
1648};
1649
paul94f2b392005-06-28 12:44:16 +00001650static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001651route_set_aggregator_as (void *rule, struct prefix *prefix,
1652 route_map_object_t type, void *object)
1653{
1654 struct bgp_info *bgp_info;
1655 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001656 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001657
1658 if (type == RMAP_BGP)
1659 {
1660 bgp_info = object;
1661 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001662 ae = bgp_attr_extra_get (bgp_info->attr);
1663
1664 ae->aggregator_as = aggregator->as;
1665 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001666 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1667 }
1668
1669 return RMAP_OKAY;
1670}
1671
paul94f2b392005-06-28 12:44:16 +00001672static void *
paulfd79ac92004-10-13 05:06:08 +00001673route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001674{
1675 struct aggregator *aggregator;
1676 char as[10];
1677 char address[20];
1678
Stephen Hemminger393deb92008-08-18 14:13:29 -07001679 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001680 sscanf (arg, "%s %s", as, address);
1681
1682 aggregator->as = strtoul (as, NULL, 10);
1683 inet_aton (address, &aggregator->address);
1684
1685 return aggregator;
1686}
1687
paul94f2b392005-06-28 12:44:16 +00001688static void
paul718e3742002-12-13 20:15:29 +00001689route_set_aggregator_as_free (void *rule)
1690{
1691 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1692}
1693
1694struct route_map_rule_cmd route_set_aggregator_as_cmd =
1695{
1696 "aggregator as",
1697 route_set_aggregator_as,
1698 route_set_aggregator_as_compile,
1699 route_set_aggregator_as_free,
1700};
David Lamparter6b0655a2014-06-04 06:53:35 +02001701
paul718e3742002-12-13 20:15:29 +00001702#ifdef HAVE_IPV6
1703/* `match ipv6 address IP_ACCESS_LIST' */
1704
paul94f2b392005-06-28 12:44:16 +00001705static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001706route_match_ipv6_address (void *rule, struct prefix *prefix,
1707 route_map_object_t type, void *object)
1708{
1709 struct access_list *alist;
1710
1711 if (type == RMAP_BGP)
1712 {
1713 alist = access_list_lookup (AFI_IP6, (char *) rule);
1714 if (alist == NULL)
1715 return RMAP_NOMATCH;
1716
1717 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1718 RMAP_NOMATCH : RMAP_MATCH);
1719 }
1720 return RMAP_NOMATCH;
1721}
1722
paul94f2b392005-06-28 12:44:16 +00001723static void *
paulfd79ac92004-10-13 05:06:08 +00001724route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001725{
1726 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1727}
1728
paul94f2b392005-06-28 12:44:16 +00001729static void
paul718e3742002-12-13 20:15:29 +00001730route_match_ipv6_address_free (void *rule)
1731{
1732 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1733}
1734
1735/* Route map commands for ip address matching. */
1736struct route_map_rule_cmd route_match_ipv6_address_cmd =
1737{
1738 "ipv6 address",
1739 route_match_ipv6_address,
1740 route_match_ipv6_address_compile,
1741 route_match_ipv6_address_free
1742};
David Lamparter6b0655a2014-06-04 06:53:35 +02001743
paul718e3742002-12-13 20:15:29 +00001744/* `match ipv6 next-hop IP_ADDRESS' */
1745
paul94f2b392005-06-28 12:44:16 +00001746static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001747route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1748 route_map_object_t type, void *object)
1749{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001750 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001751 struct bgp_info *bgp_info;
1752
1753 if (type == RMAP_BGP)
1754 {
paul718e3742002-12-13 20:15:29 +00001755 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001756
1757 if (!bgp_info->attr->extra)
1758 return RMAP_NOMATCH;
1759
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001760 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001761 return RMAP_MATCH;
1762
Paul Jakmafb982c22007-05-04 20:15:47 +00001763 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001764 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001765 return RMAP_MATCH;
1766
1767 return RMAP_NOMATCH;
1768 }
1769
1770 return RMAP_NOMATCH;
1771}
1772
paul94f2b392005-06-28 12:44:16 +00001773static void *
paulfd79ac92004-10-13 05:06:08 +00001774route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001775{
1776 struct in6_addr *address;
1777 int ret;
1778
1779 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1780
1781 ret = inet_pton (AF_INET6, arg, address);
1782 if (!ret)
1783 {
1784 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1785 return NULL;
1786 }
1787
1788 return address;
1789}
1790
paul94f2b392005-06-28 12:44:16 +00001791static void
paul718e3742002-12-13 20:15:29 +00001792route_match_ipv6_next_hop_free (void *rule)
1793{
1794 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1795}
1796
1797struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1798{
1799 "ipv6 next-hop",
1800 route_match_ipv6_next_hop,
1801 route_match_ipv6_next_hop_compile,
1802 route_match_ipv6_next_hop_free
1803};
David Lamparter6b0655a2014-06-04 06:53:35 +02001804
paul718e3742002-12-13 20:15:29 +00001805/* `match ipv6 address prefix-list PREFIX_LIST' */
1806
paul94f2b392005-06-28 12:44:16 +00001807static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001808route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1809 route_map_object_t type, void *object)
1810{
1811 struct prefix_list *plist;
1812
1813 if (type == RMAP_BGP)
1814 {
1815 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1816 if (plist == NULL)
1817 return RMAP_NOMATCH;
1818
1819 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1820 RMAP_NOMATCH : RMAP_MATCH);
1821 }
1822 return RMAP_NOMATCH;
1823}
1824
paul94f2b392005-06-28 12:44:16 +00001825static void *
paulfd79ac92004-10-13 05:06:08 +00001826route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001827{
1828 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1829}
1830
paul94f2b392005-06-28 12:44:16 +00001831static void
paul718e3742002-12-13 20:15:29 +00001832route_match_ipv6_address_prefix_list_free (void *rule)
1833{
1834 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1835}
1836
1837struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1838{
1839 "ipv6 address prefix-list",
1840 route_match_ipv6_address_prefix_list,
1841 route_match_ipv6_address_prefix_list_compile,
1842 route_match_ipv6_address_prefix_list_free
1843};
David Lamparter6b0655a2014-06-04 06:53:35 +02001844
paul718e3742002-12-13 20:15:29 +00001845/* `set ipv6 nexthop global IP_ADDRESS' */
1846
1847/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001848static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001849route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1850 route_map_object_t type, void *object)
1851{
1852 struct in6_addr *address;
1853 struct bgp_info *bgp_info;
1854
1855 if (type == RMAP_BGP)
1856 {
1857 /* Fetch routemap's rule information. */
1858 address = rule;
1859 bgp_info = object;
1860
1861 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001862 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001863
1864 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001865 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1866 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001867 }
1868
1869 return RMAP_OKAY;
1870}
1871
1872/* Route map `ip next-hop' compile function. Given string is converted
1873 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001874static void *
paulfd79ac92004-10-13 05:06:08 +00001875route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001876{
1877 int ret;
1878 struct in6_addr *address;
1879
1880 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1881
1882 ret = inet_pton (AF_INET6, arg, address);
1883
1884 if (ret == 0)
1885 {
1886 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1887 return NULL;
1888 }
1889
1890 return address;
1891}
1892
1893/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001894static void
paul718e3742002-12-13 20:15:29 +00001895route_set_ipv6_nexthop_global_free (void *rule)
1896{
1897 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1898}
1899
1900/* Route map commands for ip nexthop set. */
1901struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1902{
1903 "ipv6 next-hop global",
1904 route_set_ipv6_nexthop_global,
1905 route_set_ipv6_nexthop_global_compile,
1906 route_set_ipv6_nexthop_global_free
1907};
David Lamparter6b0655a2014-06-04 06:53:35 +02001908
paul718e3742002-12-13 20:15:29 +00001909/* `set ipv6 nexthop local IP_ADDRESS' */
1910
1911/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001912static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001913route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1914 route_map_object_t type, void *object)
1915{
1916 struct in6_addr *address;
1917 struct bgp_info *bgp_info;
1918
1919 if (type == RMAP_BGP)
1920 {
1921 /* Fetch routemap's rule information. */
1922 address = rule;
1923 bgp_info = object;
1924
1925 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001926 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001927
1928 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001929 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1930 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001931 }
1932
1933 return RMAP_OKAY;
1934}
1935
1936/* Route map `ip nexthop' compile function. Given string is converted
1937 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001938static void *
paulfd79ac92004-10-13 05:06:08 +00001939route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001940{
1941 int ret;
1942 struct in6_addr *address;
1943
1944 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1945
1946 ret = inet_pton (AF_INET6, arg, address);
1947
1948 if (ret == 0)
1949 {
1950 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1951 return NULL;
1952 }
1953
1954 return address;
1955}
1956
1957/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001958static void
paul718e3742002-12-13 20:15:29 +00001959route_set_ipv6_nexthop_local_free (void *rule)
1960{
1961 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1962}
1963
1964/* Route map commands for ip nexthop set. */
1965struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1966{
1967 "ipv6 next-hop local",
1968 route_set_ipv6_nexthop_local,
1969 route_set_ipv6_nexthop_local_compile,
1970 route_set_ipv6_nexthop_local_free
1971};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07001972
1973/* `set ipv6 nexthop peer-address' */
1974
1975/* Set nexthop to object. ojbect must be pointer to struct attr. */
1976static route_map_result_t
1977route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
1978 route_map_object_t type, void *object)
1979{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07001980 struct in6_addr peer_address;
1981 struct bgp_info *bgp_info;
1982 struct peer *peer;
1983 char peer_addr_buf[INET6_ADDRSTRLEN];
1984
1985 if (type == RMAP_BGP)
1986 {
1987 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07001988 bgp_info = object;
1989 peer = bgp_info->peer;
1990
1991 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
1992 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
1993 && peer->su_remote
1994 && sockunion_family (peer->su_remote) == AF_INET6)
1995 {
1996 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
1997 peer_addr_buf,
1998 INET6_ADDRSTRLEN),
1999 &peer_address);
2000 }
2001 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2002 && peer->su_local
2003 && sockunion_family (peer->su_local) == AF_INET6)
2004 {
2005 inet_pton (AF_INET, sockunion2str (peer->su_local,
2006 peer_addr_buf,
2007 INET6_ADDRSTRLEN),
2008 &peer_address);
2009 }
2010
2011 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2012 {
2013 /* Set next hop value. */
2014 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2015
2016 /* Set nexthop length. */
2017 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2018 bgp_info->attr->extra->mp_nexthop_len = 32;
2019 }
2020 else
2021 {
2022 /* Set next hop value. */
2023 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2024
2025 /* Set nexthop length. */
2026 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2027 bgp_info->attr->extra->mp_nexthop_len = 16;
2028 }
2029 }
2030
2031 return RMAP_OKAY;
2032}
2033
2034/* Route map `ip next-hop' compile function. Given string is converted
2035 to struct in_addr structure. */
2036static void *
2037route_set_ipv6_nexthop_peer_compile (const char *arg)
2038{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002039 int *rins = NULL;
2040
2041 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2042 *rins = 1;
2043
2044 return rins;
2045}
2046
2047/* Free route map's compiled `ip next-hop' value. */
2048static void
2049route_set_ipv6_nexthop_peer_free (void *rule)
2050{
2051 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2052}
2053
2054/* Route map commands for ip nexthop set. */
2055struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2056{
2057 "ipv6 next-hop peer-address",
2058 route_set_ipv6_nexthop_peer,
2059 route_set_ipv6_nexthop_peer_compile,
2060 route_set_ipv6_nexthop_peer_free
2061};
2062
paul718e3742002-12-13 20:15:29 +00002063#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02002064
paul718e3742002-12-13 20:15:29 +00002065/* `set vpnv4 nexthop A.B.C.D' */
2066
paul94f2b392005-06-28 12:44:16 +00002067static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002068route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2069 route_map_object_t type, void *object)
2070{
2071 struct in_addr *address;
2072 struct bgp_info *bgp_info;
2073
2074 if (type == RMAP_BGP)
2075 {
2076 /* Fetch routemap's rule information. */
2077 address = rule;
2078 bgp_info = object;
2079
2080 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002081 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002082 }
2083
2084 return RMAP_OKAY;
2085}
2086
paul94f2b392005-06-28 12:44:16 +00002087static void *
paulfd79ac92004-10-13 05:06:08 +00002088route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002089{
2090 int ret;
2091 struct in_addr *address;
2092
2093 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2094
2095 ret = inet_aton (arg, address);
2096
2097 if (ret == 0)
2098 {
2099 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2100 return NULL;
2101 }
2102
2103 return address;
2104}
2105
paul94f2b392005-06-28 12:44:16 +00002106static void
paul718e3742002-12-13 20:15:29 +00002107route_set_vpnv4_nexthop_free (void *rule)
2108{
2109 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2110}
2111
2112/* Route map commands for ip nexthop set. */
2113struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2114{
2115 "vpnv4 next-hop",
2116 route_set_vpnv4_nexthop,
2117 route_set_vpnv4_nexthop_compile,
2118 route_set_vpnv4_nexthop_free
2119};
David Lamparter6b0655a2014-06-04 06:53:35 +02002120
paul718e3742002-12-13 20:15:29 +00002121/* `set originator-id' */
2122
2123/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002124static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002125route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2126{
2127 struct in_addr *address;
2128 struct bgp_info *bgp_info;
2129
2130 if (type == RMAP_BGP)
2131 {
2132 address = rule;
2133 bgp_info = object;
2134
2135 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002136 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002137 }
2138
2139 return RMAP_OKAY;
2140}
2141
2142/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002143static void *
paulfd79ac92004-10-13 05:06:08 +00002144route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002145{
2146 int ret;
2147 struct in_addr *address;
2148
2149 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2150
2151 ret = inet_aton (arg, address);
2152
2153 if (ret == 0)
2154 {
2155 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2156 return NULL;
2157 }
2158
2159 return address;
2160}
2161
2162/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002163static void
paul718e3742002-12-13 20:15:29 +00002164route_set_originator_id_free (void *rule)
2165{
2166 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2167}
2168
Timo Teräs2aa640b2014-05-20 08:57:26 +03002169/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002170struct route_map_rule_cmd route_set_originator_id_cmd =
2171{
2172 "originator-id",
2173 route_set_originator_id,
2174 route_set_originator_id_compile,
2175 route_set_originator_id_free,
2176};
David Lamparter6b0655a2014-06-04 06:53:35 +02002177
paul718e3742002-12-13 20:15:29 +00002178/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002179static int
paul718e3742002-12-13 20:15:29 +00002180bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002181 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002182{
2183 int ret;
2184
2185 ret = route_map_add_match (index, command, arg);
2186 if (ret)
2187 {
2188 switch (ret)
2189 {
2190 case RMAP_RULE_MISSING:
2191 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2192 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002193 case RMAP_COMPILE_ERROR:
2194 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2195 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002196 }
2197 }
2198 return CMD_SUCCESS;
2199}
2200
2201/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002202static int
paul718e3742002-12-13 20:15:29 +00002203bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002204 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002205{
2206 int ret;
2207
2208 ret = route_map_delete_match (index, command, arg);
2209 if (ret)
2210 {
2211 switch (ret)
2212 {
2213 case RMAP_RULE_MISSING:
2214 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2215 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002216 case RMAP_COMPILE_ERROR:
2217 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2218 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002219 }
2220 }
2221 return CMD_SUCCESS;
2222}
2223
2224/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002225static int
paul718e3742002-12-13 20:15:29 +00002226bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002227 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002228{
2229 int ret;
2230
2231 ret = route_map_add_set (index, command, arg);
2232 if (ret)
2233 {
2234 switch (ret)
2235 {
2236 case RMAP_RULE_MISSING:
2237 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2238 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002239 case RMAP_COMPILE_ERROR:
2240 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2241 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002242 }
2243 }
2244 return CMD_SUCCESS;
2245}
2246
2247/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002248static int
paul718e3742002-12-13 20:15:29 +00002249bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002250 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002251{
2252 int ret;
2253
2254 ret = route_map_delete_set (index, command, arg);
2255 if (ret)
2256 {
2257 switch (ret)
2258 {
2259 case RMAP_RULE_MISSING:
2260 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2261 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002262 case RMAP_COMPILE_ERROR:
2263 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2264 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002265 }
2266 }
2267 return CMD_SUCCESS;
2268}
2269
2270/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002271static void
paulfd79ac92004-10-13 05:06:08 +00002272bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002273{
2274 int i;
2275 afi_t afi;
2276 safi_t safi;
2277 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002278 struct listnode *node, *nnode;
2279 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002280 struct bgp *bgp;
2281 struct peer *peer;
2282 struct peer_group *group;
2283 struct bgp_filter *filter;
2284 struct bgp_node *bn;
2285 struct bgp_static *bgp_static;
2286
2287 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002288 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002289 {
paul1eb8ef22005-04-07 07:30:20 +00002290 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002291 {
2292 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2293 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2294 {
2295 filter = &peer->filter[afi][safi];
2296
paulfee0f4c2004-09-13 05:12:46 +00002297 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002298 {
2299 if (filter->map[direct].name)
2300 filter->map[direct].map =
2301 route_map_lookup_by_name (filter->map[direct].name);
2302 else
2303 filter->map[direct].map = NULL;
2304 }
2305
2306 if (filter->usmap.name)
2307 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2308 else
2309 filter->usmap.map = NULL;
2310 }
2311 }
paul1eb8ef22005-04-07 07:30:20 +00002312 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
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 = &group->conf->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 }
2334 }
2335
2336 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002337 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002338 {
paul1eb8ef22005-04-07 07:30:20 +00002339 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002340 {
2341 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2342 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2343 {
2344 if (peer->default_rmap[afi][safi].name)
2345 peer->default_rmap[afi][safi].map =
2346 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2347 else
2348 peer->default_rmap[afi][safi].map = NULL;
2349 }
2350 }
2351 }
2352
2353 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002354 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002355 {
2356 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2357 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2358 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2359 bn = bgp_route_next (bn))
2360 if ((bgp_static = bn->info) != NULL)
2361 {
2362 if (bgp_static->rmap.name)
2363 bgp_static->rmap.map =
2364 route_map_lookup_by_name (bgp_static->rmap.name);
2365 else
2366 bgp_static->rmap.map = NULL;
2367 }
2368 }
2369
2370 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002371 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002372 {
2373 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2374 {
2375 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2376 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2377 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2378#ifdef HAVE_IPV6
2379 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2380 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2381 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2382#endif /* HAVE_IPV6 */
2383 }
2384 }
2385}
David Lamparter6b0655a2014-06-04 06:53:35 +02002386
paulfee0f4c2004-09-13 05:12:46 +00002387DEFUN (match_peer,
2388 match_peer_cmd,
2389 "match peer (A.B.C.D|X:X::X:X)",
2390 MATCH_STR
2391 "Match peer address\n"
2392 "IPv6 address of peer\n"
2393 "IP address of peer\n")
2394{
2395 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2396}
2397
2398DEFUN (match_peer_local,
2399 match_peer_local_cmd,
2400 "match peer local",
2401 MATCH_STR
2402 "Match peer address\n"
2403 "Static or Redistributed routes\n")
2404{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002405 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002406}
2407
2408DEFUN (no_match_peer,
2409 no_match_peer_cmd,
2410 "no match peer",
2411 NO_STR
2412 MATCH_STR
2413 "Match peer address\n")
2414{
2415 if (argc == 0)
2416 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2417
2418 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2419}
2420
2421ALIAS (no_match_peer,
2422 no_match_peer_val_cmd,
2423 "no match peer (A.B.C.D|X:X::X:X)",
2424 NO_STR
2425 MATCH_STR
2426 "Match peer address\n"
2427 "IPv6 address of peer\n"
2428 "IP address of peer\n")
2429
2430ALIAS (no_match_peer,
2431 no_match_peer_local_cmd,
2432 "no match peer local",
2433 NO_STR
2434 MATCH_STR
2435 "Match peer address\n"
2436 "Static or Redistributed routes\n")
2437
paul718e3742002-12-13 20:15:29 +00002438DEFUN (match_ip_address,
2439 match_ip_address_cmd,
2440 "match ip address (<1-199>|<1300-2699>|WORD)",
2441 MATCH_STR
2442 IP_STR
2443 "Match address of route\n"
2444 "IP access-list number\n"
2445 "IP access-list number (expanded range)\n"
2446 "IP Access-list name\n")
2447{
2448 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2449}
2450
2451DEFUN (no_match_ip_address,
2452 no_match_ip_address_cmd,
2453 "no match ip address",
2454 NO_STR
2455 MATCH_STR
2456 IP_STR
2457 "Match address of route\n")
2458{
2459 if (argc == 0)
2460 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2461
2462 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2463}
2464
2465ALIAS (no_match_ip_address,
2466 no_match_ip_address_val_cmd,
2467 "no match ip address (<1-199>|<1300-2699>|WORD)",
2468 NO_STR
2469 MATCH_STR
2470 IP_STR
2471 "Match address of route\n"
2472 "IP access-list number\n"
2473 "IP access-list number (expanded range)\n"
2474 "IP Access-list name\n")
2475
2476DEFUN (match_ip_next_hop,
2477 match_ip_next_hop_cmd,
2478 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2479 MATCH_STR
2480 IP_STR
2481 "Match next-hop address of route\n"
2482 "IP access-list number\n"
2483 "IP access-list number (expanded range)\n"
2484 "IP Access-list name\n")
2485{
2486 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2487}
2488
2489DEFUN (no_match_ip_next_hop,
2490 no_match_ip_next_hop_cmd,
2491 "no match ip next-hop",
2492 NO_STR
2493 MATCH_STR
2494 IP_STR
2495 "Match next-hop address of route\n")
2496{
2497 if (argc == 0)
2498 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2499
2500 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2501}
2502
2503ALIAS (no_match_ip_next_hop,
2504 no_match_ip_next_hop_val_cmd,
2505 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2506 NO_STR
2507 MATCH_STR
2508 IP_STR
2509 "Match next-hop address of route\n"
2510 "IP access-list number\n"
2511 "IP access-list number (expanded range)\n"
2512 "IP Access-list name\n")
2513
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002514/* match probability { */
2515
2516DEFUN (match_probability,
2517 match_probability_cmd,
2518 "match probability <0-100>",
2519 MATCH_STR
2520 "Match portion of routes defined by percentage value\n"
2521 "Percentage of routes\n")
2522{
2523 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2524}
2525
2526DEFUN (no_match_probability,
2527 no_match_probability_cmd,
2528 "no match probability",
2529 NO_STR
2530 MATCH_STR
2531 "Match portion of routes defined by percentage value\n")
2532{
2533 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2534}
2535
2536ALIAS (no_match_probability,
2537 no_match_probability_val_cmd,
2538 "no match probability <1-99>",
2539 NO_STR
2540 MATCH_STR
2541 "Match portion of routes defined by percentage value\n"
2542 "Percentage of routes\n")
2543
2544/* } */
2545
hassoc1643bb2005-02-02 16:43:17 +00002546DEFUN (match_ip_route_source,
2547 match_ip_route_source_cmd,
2548 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2549 MATCH_STR
2550 IP_STR
2551 "Match advertising source address of route\n"
2552 "IP access-list number\n"
2553 "IP access-list number (expanded range)\n"
2554 "IP standard access-list name\n")
2555{
2556 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2557}
2558
2559DEFUN (no_match_ip_route_source,
2560 no_match_ip_route_source_cmd,
2561 "no match ip route-source",
2562 NO_STR
2563 MATCH_STR
2564 IP_STR
2565 "Match advertising source address of route\n")
2566{
2567 if (argc == 0)
2568 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2569
2570 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2571}
2572
2573ALIAS (no_match_ip_route_source,
2574 no_match_ip_route_source_val_cmd,
2575 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2576 NO_STR
2577 MATCH_STR
2578 IP_STR
2579 "Match advertising source address of route\n"
2580 "IP access-list number\n"
2581 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002582 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002583
paul718e3742002-12-13 20:15:29 +00002584DEFUN (match_ip_address_prefix_list,
2585 match_ip_address_prefix_list_cmd,
2586 "match ip address prefix-list WORD",
2587 MATCH_STR
2588 IP_STR
2589 "Match address of route\n"
2590 "Match entries of prefix-lists\n"
2591 "IP prefix-list name\n")
2592{
2593 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2594}
2595
2596DEFUN (no_match_ip_address_prefix_list,
2597 no_match_ip_address_prefix_list_cmd,
2598 "no match ip address prefix-list",
2599 NO_STR
2600 MATCH_STR
2601 IP_STR
2602 "Match address of route\n"
2603 "Match entries of prefix-lists\n")
2604{
2605 if (argc == 0)
2606 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2607
2608 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2609}
2610
2611ALIAS (no_match_ip_address_prefix_list,
2612 no_match_ip_address_prefix_list_val_cmd,
2613 "no match ip address prefix-list WORD",
2614 NO_STR
2615 MATCH_STR
2616 IP_STR
2617 "Match address of route\n"
2618 "Match entries of prefix-lists\n"
2619 "IP prefix-list name\n")
2620
2621DEFUN (match_ip_next_hop_prefix_list,
2622 match_ip_next_hop_prefix_list_cmd,
2623 "match ip next-hop prefix-list WORD",
2624 MATCH_STR
2625 IP_STR
2626 "Match next-hop address of route\n"
2627 "Match entries of prefix-lists\n"
2628 "IP prefix-list name\n")
2629{
2630 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2631}
2632
2633DEFUN (no_match_ip_next_hop_prefix_list,
2634 no_match_ip_next_hop_prefix_list_cmd,
2635 "no match ip next-hop prefix-list",
2636 NO_STR
2637 MATCH_STR
2638 IP_STR
2639 "Match next-hop address of route\n"
2640 "Match entries of prefix-lists\n")
2641{
2642 if (argc == 0)
2643 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2644
2645 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2646}
2647
2648ALIAS (no_match_ip_next_hop_prefix_list,
2649 no_match_ip_next_hop_prefix_list_val_cmd,
2650 "no match ip next-hop prefix-list WORD",
2651 NO_STR
2652 MATCH_STR
2653 IP_STR
2654 "Match next-hop address of route\n"
2655 "Match entries of prefix-lists\n"
2656 "IP prefix-list name\n")
2657
hassoc1643bb2005-02-02 16:43:17 +00002658DEFUN (match_ip_route_source_prefix_list,
2659 match_ip_route_source_prefix_list_cmd,
2660 "match ip route-source prefix-list WORD",
2661 MATCH_STR
2662 IP_STR
2663 "Match advertising source address of route\n"
2664 "Match entries of prefix-lists\n"
2665 "IP prefix-list name\n")
2666{
2667 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2668}
2669
2670DEFUN (no_match_ip_route_source_prefix_list,
2671 no_match_ip_route_source_prefix_list_cmd,
2672 "no match ip route-source prefix-list",
2673 NO_STR
2674 MATCH_STR
2675 IP_STR
2676 "Match advertising source address of route\n"
2677 "Match entries of prefix-lists\n")
2678{
2679 if (argc == 0)
2680 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2681
2682 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2683}
2684
2685ALIAS (no_match_ip_route_source_prefix_list,
2686 no_match_ip_route_source_prefix_list_val_cmd,
2687 "no match ip route-source prefix-list WORD",
2688 NO_STR
2689 MATCH_STR
2690 IP_STR
2691 "Match advertising source address of route\n"
2692 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002693 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002694
paul718e3742002-12-13 20:15:29 +00002695DEFUN (match_metric,
2696 match_metric_cmd,
2697 "match metric <0-4294967295>",
2698 MATCH_STR
2699 "Match metric of route\n"
2700 "Metric value\n")
2701{
2702 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2703}
2704
2705DEFUN (no_match_metric,
2706 no_match_metric_cmd,
2707 "no match metric",
2708 NO_STR
2709 MATCH_STR
2710 "Match metric of route\n")
2711{
2712 if (argc == 0)
2713 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2714
2715 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2716}
2717
2718ALIAS (no_match_metric,
2719 no_match_metric_val_cmd,
2720 "no match metric <0-4294967295>",
2721 NO_STR
2722 MATCH_STR
2723 "Match metric of route\n"
2724 "Metric value\n")
2725
2726DEFUN (match_community,
2727 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002728 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002729 MATCH_STR
2730 "Match BGP community list\n"
2731 "Community-list number (standard)\n"
2732 "Community-list number (expanded)\n"
2733 "Community-list name\n")
2734{
2735 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2736}
2737
2738DEFUN (match_community_exact,
2739 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002740 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002741 MATCH_STR
2742 "Match BGP community list\n"
2743 "Community-list number (standard)\n"
2744 "Community-list number (expanded)\n"
2745 "Community-list name\n"
2746 "Do exact matching of communities\n")
2747{
2748 int ret;
2749 char *argstr;
2750
2751 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2752 strlen (argv[0]) + strlen ("exact-match") + 2);
2753
2754 sprintf (argstr, "%s exact-match", argv[0]);
2755
2756 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2757
2758 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2759
2760 return ret;
2761}
2762
2763DEFUN (no_match_community,
2764 no_match_community_cmd,
2765 "no match community",
2766 NO_STR
2767 MATCH_STR
2768 "Match BGP community list\n")
2769{
2770 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2771}
2772
2773ALIAS (no_match_community,
2774 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002775 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002776 NO_STR
2777 MATCH_STR
2778 "Match BGP community list\n"
2779 "Community-list number (standard)\n"
2780 "Community-list number (expanded)\n"
2781 "Community-list name\n")
2782
2783ALIAS (no_match_community,
2784 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002785 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002786 NO_STR
2787 MATCH_STR
2788 "Match BGP community list\n"
2789 "Community-list number (standard)\n"
2790 "Community-list number (expanded)\n"
2791 "Community-list name\n"
2792 "Do exact matching of communities\n")
2793
paul73ffb252003-04-19 15:49:49 +00002794DEFUN (match_ecommunity,
2795 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002796 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002797 MATCH_STR
2798 "Match BGP/VPN extended community list\n"
2799 "Extended community-list number (standard)\n"
2800 "Extended community-list number (expanded)\n"
2801 "Extended community-list name\n")
2802{
2803 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2804}
2805
2806DEFUN (no_match_ecommunity,
2807 no_match_ecommunity_cmd,
2808 "no match extcommunity",
2809 NO_STR
2810 MATCH_STR
2811 "Match BGP/VPN extended community list\n")
2812{
2813 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2814}
2815
2816ALIAS (no_match_ecommunity,
2817 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002818 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002819 NO_STR
2820 MATCH_STR
2821 "Match BGP/VPN extended community list\n"
2822 "Extended community-list number (standard)\n"
2823 "Extended community-list number (expanded)\n"
2824 "Extended community-list name\n")
2825
paul718e3742002-12-13 20:15:29 +00002826DEFUN (match_aspath,
2827 match_aspath_cmd,
2828 "match as-path WORD",
2829 MATCH_STR
2830 "Match BGP AS path list\n"
2831 "AS path access-list name\n")
2832{
2833 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2834}
2835
2836DEFUN (no_match_aspath,
2837 no_match_aspath_cmd,
2838 "no match as-path",
2839 NO_STR
2840 MATCH_STR
2841 "Match BGP AS path list\n")
2842{
2843 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2844}
2845
2846ALIAS (no_match_aspath,
2847 no_match_aspath_val_cmd,
2848 "no match as-path WORD",
2849 NO_STR
2850 MATCH_STR
2851 "Match BGP AS path list\n"
2852 "AS path access-list name\n")
2853
2854DEFUN (match_origin,
2855 match_origin_cmd,
2856 "match origin (egp|igp|incomplete)",
2857 MATCH_STR
2858 "BGP origin code\n"
2859 "remote EGP\n"
2860 "local IGP\n"
2861 "unknown heritage\n")
2862{
2863 if (strncmp (argv[0], "igp", 2) == 0)
2864 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2865 if (strncmp (argv[0], "egp", 1) == 0)
2866 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2867 if (strncmp (argv[0], "incomplete", 2) == 0)
2868 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2869
2870 return CMD_WARNING;
2871}
2872
2873DEFUN (no_match_origin,
2874 no_match_origin_cmd,
2875 "no match origin",
2876 NO_STR
2877 MATCH_STR
2878 "BGP origin code\n")
2879{
2880 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2881}
2882
2883ALIAS (no_match_origin,
2884 no_match_origin_val_cmd,
2885 "no match origin (egp|igp|incomplete)",
2886 NO_STR
2887 MATCH_STR
2888 "BGP origin code\n"
2889 "remote EGP\n"
2890 "local IGP\n"
2891 "unknown heritage\n")
2892
2893DEFUN (set_ip_nexthop,
2894 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002895 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002896 SET_STR
2897 IP_STR
2898 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002899 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002900{
2901 union sockunion su;
2902 int ret;
2903
2904 ret = str2sockunion (argv[0], &su);
2905 if (ret < 0)
2906 {
2907 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2908 return CMD_WARNING;
2909 }
2910
2911 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2912}
2913
paulaf5cd0a2003-11-02 07:24:40 +00002914DEFUN (set_ip_nexthop_peer,
2915 set_ip_nexthop_peer_cmd,
2916 "set ip next-hop peer-address",
2917 SET_STR
2918 IP_STR
2919 "Next hop address\n"
2920 "Use peer address (for BGP only)\n")
2921{
2922 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2923}
2924
paul94f2b392005-06-28 12:44:16 +00002925DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002926 no_set_ip_nexthop_peer_cmd,
2927 "no set ip next-hop peer-address",
2928 NO_STR
2929 SET_STR
2930 IP_STR
2931 "Next hop address\n"
2932 "Use peer address (for BGP only)\n")
2933{
2934 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2935}
2936
2937
paul718e3742002-12-13 20:15:29 +00002938DEFUN (no_set_ip_nexthop,
2939 no_set_ip_nexthop_cmd,
2940 "no set ip next-hop",
2941 NO_STR
2942 SET_STR
paul718e3742002-12-13 20:15:29 +00002943 "Next hop address\n")
2944{
paulaf5cd0a2003-11-02 07:24:40 +00002945 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002946 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2947
2948 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2949}
2950
2951ALIAS (no_set_ip_nexthop,
2952 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002953 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002954 NO_STR
2955 SET_STR
2956 IP_STR
2957 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002958 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002959
2960DEFUN (set_metric,
2961 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002962 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002963 SET_STR
2964 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002965 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002966{
2967 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2968}
2969
paul73ffb252003-04-19 15:49:49 +00002970ALIAS (set_metric,
2971 set_metric_addsub_cmd,
2972 "set metric <+/-metric>",
2973 SET_STR
2974 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002975 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002976
paul718e3742002-12-13 20:15:29 +00002977DEFUN (no_set_metric,
2978 no_set_metric_cmd,
2979 "no set metric",
2980 NO_STR
2981 SET_STR
2982 "Metric value for destination routing protocol\n")
2983{
2984 if (argc == 0)
2985 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2986
2987 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2988}
2989
2990ALIAS (no_set_metric,
2991 no_set_metric_val_cmd,
2992 "no set metric <0-4294967295>",
2993 NO_STR
2994 SET_STR
2995 "Metric value for destination routing protocol\n"
2996 "Metric value\n")
2997
2998DEFUN (set_local_pref,
2999 set_local_pref_cmd,
3000 "set local-preference <0-4294967295>",
3001 SET_STR
3002 "BGP local preference path attribute\n"
3003 "Preference value\n")
3004{
3005 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3006}
3007
3008DEFUN (no_set_local_pref,
3009 no_set_local_pref_cmd,
3010 "no set local-preference",
3011 NO_STR
3012 SET_STR
3013 "BGP local preference path attribute\n")
3014{
3015 if (argc == 0)
3016 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3017
3018 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3019}
3020
3021ALIAS (no_set_local_pref,
3022 no_set_local_pref_val_cmd,
3023 "no set local-preference <0-4294967295>",
3024 NO_STR
3025 SET_STR
3026 "BGP local preference path attribute\n"
3027 "Preference value\n")
3028
3029DEFUN (set_weight,
3030 set_weight_cmd,
3031 "set weight <0-4294967295>",
3032 SET_STR
3033 "BGP weight for routing table\n"
3034 "Weight value\n")
3035{
3036 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3037}
3038
3039DEFUN (no_set_weight,
3040 no_set_weight_cmd,
3041 "no set weight",
3042 NO_STR
3043 SET_STR
3044 "BGP weight for routing table\n")
3045{
3046 if (argc == 0)
3047 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3048
3049 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3050}
3051
3052ALIAS (no_set_weight,
3053 no_set_weight_val_cmd,
3054 "no set weight <0-4294967295>",
3055 NO_STR
3056 SET_STR
3057 "BGP weight for routing table\n"
3058 "Weight value\n")
3059
3060DEFUN (set_aspath_prepend,
3061 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003062 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003063 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003064 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003065 "Prepend to the as-path\n"
3066 "AS number\n")
3067{
3068 int ret;
3069 char *str;
3070
3071 str = argv_concat (argv, argc, 0);
3072 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3073 XFREE (MTYPE_TMP, str);
3074
3075 return ret;
3076}
3077
Timo Teräs85c854a2014-09-30 11:31:53 +03003078ALIAS (set_aspath_prepend,
3079 set_aspath_prepend_lastas_cmd,
3080 "set as-path prepend (last-as) <1-10>",
3081 SET_STR
3082 "Transform BGP AS_PATH attribute\n"
3083 "Prepend to the as-path\n"
3084 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003085 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003086
paul718e3742002-12-13 20:15:29 +00003087DEFUN (no_set_aspath_prepend,
3088 no_set_aspath_prepend_cmd,
3089 "no set as-path prepend",
3090 NO_STR
3091 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003092 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003093 "Prepend to the as-path\n")
3094{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003095 int ret;
3096 char *str;
3097
3098 if (argc == 0)
3099 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3100
3101 str = argv_concat (argv, argc, 0);
3102 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3103 XFREE (MTYPE_TMP, str);
3104 return ret;
paul718e3742002-12-13 20:15:29 +00003105}
3106
3107ALIAS (no_set_aspath_prepend,
3108 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003109 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003110 NO_STR
3111 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003112 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003113 "Prepend to the as-path\n"
3114 "AS number\n")
3115
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003116DEFUN (set_aspath_exclude,
3117 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003118 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003119 SET_STR
3120 "Transform BGP AS-path attribute\n"
3121 "Exclude from the as-path\n"
3122 "AS number\n")
3123{
3124 int ret;
3125 char *str;
3126
3127 str = argv_concat (argv, argc, 0);
3128 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3129 XFREE (MTYPE_TMP, str);
3130 return ret;
3131}
3132
3133DEFUN (no_set_aspath_exclude,
3134 no_set_aspath_exclude_cmd,
3135 "no set as-path exclude",
3136 NO_STR
3137 SET_STR
3138 "Transform BGP AS_PATH attribute\n"
3139 "Exclude from the as-path\n")
3140{
3141 int ret;
3142 char *str;
3143
3144 if (argc == 0)
3145 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3146
3147 str = argv_concat (argv, argc, 0);
3148 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3149 XFREE (MTYPE_TMP, str);
3150 return ret;
3151}
3152
3153ALIAS (no_set_aspath_exclude,
3154 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003155 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003156 NO_STR
3157 SET_STR
3158 "Transform BGP AS_PATH attribute\n"
3159 "Exclude from the as-path\n"
3160 "AS number\n")
3161
paul718e3742002-12-13 20:15:29 +00003162DEFUN (set_community,
3163 set_community_cmd,
3164 "set community .AA:NN",
3165 SET_STR
3166 "BGP community attribute\n"
3167 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3168{
3169 int i;
3170 int first = 0;
3171 int additive = 0;
3172 struct buffer *b;
3173 struct community *com = NULL;
3174 char *str;
3175 char *argstr;
3176 int ret;
3177
3178 b = buffer_new (1024);
3179
3180 for (i = 0; i < argc; i++)
3181 {
3182 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3183 {
3184 additive = 1;
3185 continue;
3186 }
3187
3188 if (first)
3189 buffer_putc (b, ' ');
3190 else
3191 first = 1;
3192
3193 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3194 {
3195 buffer_putstr (b, "internet");
3196 continue;
3197 }
3198 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3199 {
3200 buffer_putstr (b, "local-AS");
3201 continue;
3202 }
3203 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3204 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3205 {
3206 buffer_putstr (b, "no-advertise");
3207 continue;
3208 }
3209 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3210 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3211 {
3212 buffer_putstr (b, "no-export");
3213 continue;
3214 }
3215 buffer_putstr (b, argv[i]);
3216 }
3217 buffer_putc (b, '\0');
3218
3219 /* Fetch result string then compile it to communities attribute. */
3220 str = buffer_getstr (b);
3221 buffer_free (b);
3222
3223 if (str)
3224 {
3225 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003226 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003227 }
3228
3229 /* Can't compile user input into communities attribute. */
3230 if (! com)
3231 {
3232 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3233 return CMD_WARNING;
3234 }
3235
3236 /* Set communites attribute string. */
3237 str = community_str (com);
3238
3239 if (additive)
3240 {
3241 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3242 strcpy (argstr, str);
3243 strcpy (argstr + strlen (str), " additive");
3244 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3245 XFREE (MTYPE_TMP, argstr);
3246 }
3247 else
3248 ret = bgp_route_set_add (vty, vty->index, "community", str);
3249
3250 community_free (com);
3251
3252 return ret;
3253}
3254
3255DEFUN (set_community_none,
3256 set_community_none_cmd,
3257 "set community none",
3258 SET_STR
3259 "BGP community attribute\n"
3260 "No community attribute\n")
3261{
3262 return bgp_route_set_add (vty, vty->index, "community", "none");
3263}
3264
3265DEFUN (no_set_community,
3266 no_set_community_cmd,
3267 "no set community",
3268 NO_STR
3269 SET_STR
3270 "BGP community attribute\n")
3271{
3272 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3273}
3274
3275ALIAS (no_set_community,
3276 no_set_community_val_cmd,
3277 "no set community .AA:NN",
3278 NO_STR
3279 SET_STR
3280 "BGP community attribute\n"
3281 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3282
3283ALIAS (no_set_community,
3284 no_set_community_none_cmd,
3285 "no set community none",
3286 NO_STR
3287 SET_STR
3288 "BGP community attribute\n"
3289 "No community attribute\n")
3290
3291DEFUN (set_community_delete,
3292 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003293 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003294 SET_STR
3295 "set BGP community list (for deletion)\n"
3296 "Community-list number (standard)\n"
3297 "Communitly-list number (expanded)\n"
3298 "Community-list name\n"
3299 "Delete matching communities\n")
3300{
3301 char *str;
3302
3303 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3304 strcpy (str, argv[0]);
3305 strcpy (str + strlen (argv[0]), " delete");
3306
3307 bgp_route_set_add (vty, vty->index, "comm-list", str);
3308
3309 XFREE (MTYPE_TMP, str);
3310 return CMD_SUCCESS;
3311}
3312
3313DEFUN (no_set_community_delete,
3314 no_set_community_delete_cmd,
3315 "no set comm-list",
3316 NO_STR
3317 SET_STR
3318 "set BGP community list (for deletion)\n")
3319{
3320 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3321}
3322
3323ALIAS (no_set_community_delete,
3324 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003325 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003326 NO_STR
3327 SET_STR
3328 "set BGP community list (for deletion)\n"
3329 "Community-list number (standard)\n"
3330 "Communitly-list number (expanded)\n"
3331 "Community-list name\n"
3332 "Delete matching communities\n")
3333
3334DEFUN (set_ecommunity_rt,
3335 set_ecommunity_rt_cmd,
3336 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3337 SET_STR
3338 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003339 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003340 "VPN extended community\n")
3341{
3342 int ret;
3343 char *str;
3344
3345 str = argv_concat (argv, argc, 0);
3346 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3347 XFREE (MTYPE_TMP, str);
3348
3349 return ret;
3350}
3351
3352DEFUN (no_set_ecommunity_rt,
3353 no_set_ecommunity_rt_cmd,
3354 "no set extcommunity rt",
3355 NO_STR
3356 SET_STR
3357 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003358 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003359{
3360 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3361}
3362
3363ALIAS (no_set_ecommunity_rt,
3364 no_set_ecommunity_rt_val_cmd,
3365 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3366 NO_STR
3367 SET_STR
3368 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003369 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003370 "VPN extended community\n")
3371
3372DEFUN (set_ecommunity_soo,
3373 set_ecommunity_soo_cmd,
3374 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3375 SET_STR
3376 "BGP extended community attribute\n"
3377 "Site-of-Origin extended community\n"
3378 "VPN extended community\n")
3379{
3380 int ret;
3381 char *str;
3382
3383 str = argv_concat (argv, argc, 0);
3384 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3385 XFREE (MTYPE_TMP, str);
3386 return ret;
3387}
3388
3389DEFUN (no_set_ecommunity_soo,
3390 no_set_ecommunity_soo_cmd,
3391 "no set extcommunity soo",
3392 NO_STR
3393 SET_STR
3394 "BGP extended community attribute\n"
3395 "Site-of-Origin extended community\n")
3396{
3397 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3398}
3399
3400ALIAS (no_set_ecommunity_soo,
3401 no_set_ecommunity_soo_val_cmd,
3402 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3403 NO_STR
3404 SET_STR
3405 "BGP extended community attribute\n"
3406 "Site-of-Origin extended community\n"
3407 "VPN extended community\n")
3408
3409DEFUN (set_origin,
3410 set_origin_cmd,
3411 "set origin (egp|igp|incomplete)",
3412 SET_STR
3413 "BGP origin code\n"
3414 "remote EGP\n"
3415 "local IGP\n"
3416 "unknown heritage\n")
3417{
3418 if (strncmp (argv[0], "igp", 2) == 0)
3419 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3420 if (strncmp (argv[0], "egp", 1) == 0)
3421 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3422 if (strncmp (argv[0], "incomplete", 2) == 0)
3423 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3424
3425 return CMD_WARNING;
3426}
3427
3428DEFUN (no_set_origin,
3429 no_set_origin_cmd,
3430 "no set origin",
3431 NO_STR
3432 SET_STR
3433 "BGP origin code\n")
3434{
3435 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3436}
3437
3438ALIAS (no_set_origin,
3439 no_set_origin_val_cmd,
3440 "no set origin (egp|igp|incomplete)",
3441 NO_STR
3442 SET_STR
3443 "BGP origin code\n"
3444 "remote EGP\n"
3445 "local IGP\n"
3446 "unknown heritage\n")
3447
3448DEFUN (set_atomic_aggregate,
3449 set_atomic_aggregate_cmd,
3450 "set atomic-aggregate",
3451 SET_STR
3452 "BGP atomic aggregate attribute\n" )
3453{
3454 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3455}
3456
3457DEFUN (no_set_atomic_aggregate,
3458 no_set_atomic_aggregate_cmd,
3459 "no set atomic-aggregate",
3460 NO_STR
3461 SET_STR
3462 "BGP atomic aggregate attribute\n" )
3463{
3464 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3465}
3466
3467DEFUN (set_aggregator_as,
3468 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003469 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003470 SET_STR
3471 "BGP aggregator attribute\n"
3472 "AS number of aggregator\n"
3473 "AS number\n"
3474 "IP address of aggregator\n")
3475{
3476 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003477 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003478 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003479 char *argstr;
3480
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003481 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003482
paul718e3742002-12-13 20:15:29 +00003483 ret = inet_aton (argv[1], &address);
3484 if (ret == 0)
3485 {
3486 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3487 return CMD_WARNING;
3488 }
3489
3490 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3491 strlen (argv[0]) + strlen (argv[1]) + 2);
3492
3493 sprintf (argstr, "%s %s", argv[0], argv[1]);
3494
3495 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3496
3497 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3498
3499 return ret;
3500}
3501
3502DEFUN (no_set_aggregator_as,
3503 no_set_aggregator_as_cmd,
3504 "no set aggregator as",
3505 NO_STR
3506 SET_STR
3507 "BGP aggregator attribute\n"
3508 "AS number of aggregator\n")
3509{
3510 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003511 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003512 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003513 char *argstr;
3514
3515 if (argv == 0)
3516 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3517
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003518 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003519
3520 ret = inet_aton (argv[1], &address);
3521 if (ret == 0)
3522 {
3523 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3524 return CMD_WARNING;
3525 }
3526
3527 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3528 strlen (argv[0]) + strlen (argv[1]) + 2);
3529
3530 sprintf (argstr, "%s %s", argv[0], argv[1]);
3531
3532 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3533
3534 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3535
3536 return ret;
3537}
3538
3539ALIAS (no_set_aggregator_as,
3540 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003541 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003542 NO_STR
3543 SET_STR
3544 "BGP aggregator attribute\n"
3545 "AS number of aggregator\n"
3546 "AS number\n"
3547 "IP address of aggregator\n")
3548
David Lamparter6b0655a2014-06-04 06:53:35 +02003549
paul718e3742002-12-13 20:15:29 +00003550#ifdef HAVE_IPV6
3551DEFUN (match_ipv6_address,
3552 match_ipv6_address_cmd,
3553 "match ipv6 address WORD",
3554 MATCH_STR
3555 IPV6_STR
3556 "Match IPv6 address of route\n"
3557 "IPv6 access-list name\n")
3558{
3559 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3560}
3561
3562DEFUN (no_match_ipv6_address,
3563 no_match_ipv6_address_cmd,
3564 "no match ipv6 address WORD",
3565 NO_STR
3566 MATCH_STR
3567 IPV6_STR
3568 "Match IPv6 address of route\n"
3569 "IPv6 access-list name\n")
3570{
3571 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3572}
3573
3574DEFUN (match_ipv6_next_hop,
3575 match_ipv6_next_hop_cmd,
3576 "match ipv6 next-hop X:X::X:X",
3577 MATCH_STR
3578 IPV6_STR
3579 "Match IPv6 next-hop address of route\n"
3580 "IPv6 address of next hop\n")
3581{
3582 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3583}
3584
3585DEFUN (no_match_ipv6_next_hop,
3586 no_match_ipv6_next_hop_cmd,
3587 "no match ipv6 next-hop X:X::X:X",
3588 NO_STR
3589 MATCH_STR
3590 IPV6_STR
3591 "Match IPv6 next-hop address of route\n"
3592 "IPv6 address of next hop\n")
3593{
3594 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3595}
3596
3597DEFUN (match_ipv6_address_prefix_list,
3598 match_ipv6_address_prefix_list_cmd,
3599 "match ipv6 address prefix-list WORD",
3600 MATCH_STR
3601 IPV6_STR
3602 "Match address of route\n"
3603 "Match entries of prefix-lists\n"
3604 "IP prefix-list name\n")
3605{
3606 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3607}
3608
3609DEFUN (no_match_ipv6_address_prefix_list,
3610 no_match_ipv6_address_prefix_list_cmd,
3611 "no match ipv6 address prefix-list WORD",
3612 NO_STR
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_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3620}
3621
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003622DEFUN (set_ipv6_nexthop_peer,
3623 set_ipv6_nexthop_peer_cmd,
3624 "set ipv6 next-hop peer-address",
3625 SET_STR
3626 IPV6_STR
3627 "Next hop address\n"
3628 "Use peer address (for BGP only)\n")
3629{
3630 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3631}
3632
3633DEFUN (no_set_ipv6_nexthop_peer,
3634 no_set_ipv6_nexthop_peer_cmd,
3635 "no set ipv6 next-hop peer-address",
3636 NO_STR
3637 SET_STR
3638 IPV6_STR
3639 "IPv6 next-hop address\n"
3640 )
3641{
3642 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3643}
3644
paul718e3742002-12-13 20:15:29 +00003645DEFUN (set_ipv6_nexthop_global,
3646 set_ipv6_nexthop_global_cmd,
3647 "set ipv6 next-hop global X:X::X:X",
3648 SET_STR
3649 IPV6_STR
3650 "IPv6 next-hop address\n"
3651 "IPv6 global address\n"
3652 "IPv6 address of next hop\n")
3653{
3654 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3655}
3656
3657DEFUN (no_set_ipv6_nexthop_global,
3658 no_set_ipv6_nexthop_global_cmd,
3659 "no set ipv6 next-hop global",
3660 NO_STR
3661 SET_STR
3662 IPV6_STR
3663 "IPv6 next-hop address\n"
3664 "IPv6 global address\n")
3665{
3666 if (argc == 0)
3667 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3668
3669 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3670}
3671
3672ALIAS (no_set_ipv6_nexthop_global,
3673 no_set_ipv6_nexthop_global_val_cmd,
3674 "no set ipv6 next-hop global X:X::X:X",
3675 NO_STR
3676 SET_STR
3677 IPV6_STR
3678 "IPv6 next-hop address\n"
3679 "IPv6 global address\n"
3680 "IPv6 address of next hop\n")
3681
3682DEFUN (set_ipv6_nexthop_local,
3683 set_ipv6_nexthop_local_cmd,
3684 "set ipv6 next-hop local X:X::X:X",
3685 SET_STR
3686 IPV6_STR
3687 "IPv6 next-hop address\n"
3688 "IPv6 local address\n"
3689 "IPv6 address of next hop\n")
3690{
3691 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3692}
3693
3694DEFUN (no_set_ipv6_nexthop_local,
3695 no_set_ipv6_nexthop_local_cmd,
3696 "no set ipv6 next-hop local",
3697 NO_STR
3698 SET_STR
3699 IPV6_STR
3700 "IPv6 next-hop address\n"
3701 "IPv6 local address\n")
3702{
3703 if (argc == 0)
3704 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3705
3706 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3707}
3708
3709ALIAS (no_set_ipv6_nexthop_local,
3710 no_set_ipv6_nexthop_local_val_cmd,
3711 "no set ipv6 next-hop local X:X::X:X",
3712 NO_STR
3713 SET_STR
3714 IPV6_STR
3715 "IPv6 next-hop address\n"
3716 "IPv6 local address\n"
3717 "IPv6 address of next hop\n")
3718#endif /* HAVE_IPV6 */
3719
3720DEFUN (set_vpnv4_nexthop,
3721 set_vpnv4_nexthop_cmd,
3722 "set vpnv4 next-hop A.B.C.D",
3723 SET_STR
3724 "VPNv4 information\n"
3725 "VPNv4 next-hop address\n"
3726 "IP address of next hop\n")
3727{
3728 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3729}
3730
3731DEFUN (no_set_vpnv4_nexthop,
3732 no_set_vpnv4_nexthop_cmd,
3733 "no set vpnv4 next-hop",
3734 NO_STR
3735 SET_STR
3736 "VPNv4 information\n"
3737 "VPNv4 next-hop address\n")
3738{
3739 if (argc == 0)
3740 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3741
3742 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3743}
3744
3745ALIAS (no_set_vpnv4_nexthop,
3746 no_set_vpnv4_nexthop_val_cmd,
3747 "no set vpnv4 next-hop A.B.C.D",
3748 NO_STR
3749 SET_STR
3750 "VPNv4 information\n"
3751 "VPNv4 next-hop address\n"
3752 "IP address of next hop\n")
3753
3754DEFUN (set_originator_id,
3755 set_originator_id_cmd,
3756 "set originator-id A.B.C.D",
3757 SET_STR
3758 "BGP originator ID attribute\n"
3759 "IP address of originator\n")
3760{
3761 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3762}
3763
3764DEFUN (no_set_originator_id,
3765 no_set_originator_id_cmd,
3766 "no set originator-id",
3767 NO_STR
3768 SET_STR
3769 "BGP originator ID attribute\n")
3770{
3771 if (argc == 0)
3772 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3773
3774 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3775}
3776
3777ALIAS (no_set_originator_id,
3778 no_set_originator_id_val_cmd,
3779 "no set originator-id A.B.C.D",
3780 NO_STR
3781 SET_STR
3782 "BGP originator ID attribute\n"
3783 "IP address of originator\n")
3784
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003785DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003786 set_pathlimit_ttl_cmd,
3787 "set pathlimit ttl <1-255>",
3788 SET_STR
3789 "BGP AS-Pathlimit attribute\n"
3790 "Set AS-Path Hop-count TTL\n")
3791{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003792 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003793}
3794
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003795DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003796 no_set_pathlimit_ttl_cmd,
3797 "no set pathlimit ttl",
3798 NO_STR
3799 SET_STR
3800 "BGP AS-Pathlimit attribute\n"
3801 "Set AS-Path Hop-count TTL\n")
3802{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003803 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003804}
3805
3806ALIAS (no_set_pathlimit_ttl,
3807 no_set_pathlimit_ttl_val_cmd,
3808 "no set pathlimit ttl <1-255>",
3809 NO_STR
3810 MATCH_STR
3811 "BGP AS-Pathlimit attribute\n"
3812 "Set AS-Path Hop-count TTL\n")
3813
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003814DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003815 match_pathlimit_as_cmd,
3816 "match pathlimit as <1-65535>",
3817 MATCH_STR
3818 "BGP AS-Pathlimit attribute\n"
3819 "Match Pathlimit AS number\n")
3820{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003821 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003822}
3823
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003824DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003825 no_match_pathlimit_as_cmd,
3826 "no match pathlimit as",
3827 NO_STR
3828 MATCH_STR
3829 "BGP AS-Pathlimit attribute\n"
3830 "Match Pathlimit AS number\n")
3831{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003832 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003833}
3834
3835ALIAS (no_match_pathlimit_as,
3836 no_match_pathlimit_as_val_cmd,
3837 "no match pathlimit as <1-65535>",
3838 NO_STR
3839 MATCH_STR
3840 "BGP AS-Pathlimit attribute\n"
3841 "Match Pathlimit ASN\n")
3842
David Lamparter6b0655a2014-06-04 06:53:35 +02003843
paul718e3742002-12-13 20:15:29 +00003844/* Initialization of route map. */
3845void
paul94f2b392005-06-28 12:44:16 +00003846bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003847{
3848 route_map_init ();
3849 route_map_init_vty ();
3850 route_map_add_hook (bgp_route_map_update);
3851 route_map_delete_hook (bgp_route_map_update);
3852
paulfee0f4c2004-09-13 05:12:46 +00003853 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003854 route_map_install_match (&route_match_ip_address_cmd);
3855 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003856 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003857 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3858 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003859 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003860 route_map_install_match (&route_match_aspath_cmd);
3861 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003862 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003863 route_map_install_match (&route_match_metric_cmd);
3864 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003865 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003866
3867 route_map_install_set (&route_set_ip_nexthop_cmd);
3868 route_map_install_set (&route_set_local_pref_cmd);
3869 route_map_install_set (&route_set_weight_cmd);
3870 route_map_install_set (&route_set_metric_cmd);
3871 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003872 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003873 route_map_install_set (&route_set_origin_cmd);
3874 route_map_install_set (&route_set_atomic_aggregate_cmd);
3875 route_map_install_set (&route_set_aggregator_as_cmd);
3876 route_map_install_set (&route_set_community_cmd);
3877 route_map_install_set (&route_set_community_delete_cmd);
3878 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3879 route_map_install_set (&route_set_originator_id_cmd);
3880 route_map_install_set (&route_set_ecommunity_rt_cmd);
3881 route_map_install_set (&route_set_ecommunity_soo_cmd);
3882
paulfee0f4c2004-09-13 05:12:46 +00003883 install_element (RMAP_NODE, &match_peer_cmd);
3884 install_element (RMAP_NODE, &match_peer_local_cmd);
3885 install_element (RMAP_NODE, &no_match_peer_cmd);
3886 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3887 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003888 install_element (RMAP_NODE, &match_ip_address_cmd);
3889 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3890 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3891 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3892 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3893 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003894 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3895 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3896 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003897 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3898 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3899 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3900 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3901 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3902 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003903 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3904 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3905 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003906
3907 install_element (RMAP_NODE, &match_aspath_cmd);
3908 install_element (RMAP_NODE, &no_match_aspath_cmd);
3909 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3910 install_element (RMAP_NODE, &match_metric_cmd);
3911 install_element (RMAP_NODE, &no_match_metric_cmd);
3912 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3913 install_element (RMAP_NODE, &match_community_cmd);
3914 install_element (RMAP_NODE, &match_community_exact_cmd);
3915 install_element (RMAP_NODE, &no_match_community_cmd);
3916 install_element (RMAP_NODE, &no_match_community_val_cmd);
3917 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003918 install_element (RMAP_NODE, &match_ecommunity_cmd);
3919 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3920 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003921 install_element (RMAP_NODE, &match_origin_cmd);
3922 install_element (RMAP_NODE, &no_match_origin_cmd);
3923 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003924 install_element (RMAP_NODE, &match_probability_cmd);
3925 install_element (RMAP_NODE, &no_match_probability_cmd);
3926 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003927
3928 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003929 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003930 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3931 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3932 install_element (RMAP_NODE, &set_local_pref_cmd);
3933 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3934 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3935 install_element (RMAP_NODE, &set_weight_cmd);
3936 install_element (RMAP_NODE, &no_set_weight_cmd);
3937 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3938 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003939 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003940 install_element (RMAP_NODE, &no_set_metric_cmd);
3941 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3942 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03003943 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003944 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003945 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3946 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003947 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3948 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003949 install_element (RMAP_NODE, &set_origin_cmd);
3950 install_element (RMAP_NODE, &no_set_origin_cmd);
3951 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3952 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3953 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3954 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3955 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3956 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3957 install_element (RMAP_NODE, &set_community_cmd);
3958 install_element (RMAP_NODE, &set_community_none_cmd);
3959 install_element (RMAP_NODE, &no_set_community_cmd);
3960 install_element (RMAP_NODE, &no_set_community_val_cmd);
3961 install_element (RMAP_NODE, &no_set_community_none_cmd);
3962 install_element (RMAP_NODE, &set_community_delete_cmd);
3963 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3964 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3965 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3966 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3967 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3968 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3969 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3970 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3971 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3972 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3973 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3974 install_element (RMAP_NODE, &set_originator_id_cmd);
3975 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3976 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3977
3978#ifdef HAVE_IPV6
3979 route_map_install_match (&route_match_ipv6_address_cmd);
3980 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3981 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3982 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3983 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003984 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
3985
paul718e3742002-12-13 20:15:29 +00003986 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3987 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3988 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3989 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3990 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3991 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3992 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3993 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3994 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3995 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3996 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3997 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003998 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
3999 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004000#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00004001
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004002 /* AS-Pathlimit: functionality removed, commands kept for
4003 * compatibility.
4004 */
Paul Jakma41367172007-08-06 15:24:51 +00004005 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4006 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4007 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4008 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4009 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4010 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004011}