blob: 4fff0268e6bc808e777a82ec160ccee1d4f75bf9 [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"
31#ifdef HAVE_GNU_REGEX
32#include <regex.h>
33#else
34#include "regex-gnu.h"
35#endif /* HAVE_GNU_REGEX */
36#include "buffer.h"
37#include "sockunion.h"
38
39#include "bgpd/bgpd.h"
40#include "bgpd/bgp_table.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_aspath.h"
43#include "bgpd/bgp_route.h"
44#include "bgpd/bgp_regex.h"
45#include "bgpd/bgp_community.h"
46#include "bgpd/bgp_clist.h"
47#include "bgpd/bgp_filter.h"
48#include "bgpd/bgp_mplsvpn.h"
49#include "bgpd/bgp_ecommunity.h"
Paul Jakma320da872008-07-02 13:40:33 +000050#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000051
52/* Memo of route-map commands.
53
54o Cisco route-map
55
56 match as-path : Done
57 community : Done
58 interface : Not yet
59 ip address : Done
60 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000061 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000062 ip prefix-list : Done
63 ipv6 address : Done
64 ipv6 next-hop : Done
65 ipv6 route-source: (This will not be implemented by bgpd)
66 ipv6 prefix-list : Done
67 length : (This will not be implemented by bgpd)
68 metric : Done
69 route-type : (This will not be implemented by bgpd)
70 tag : (This will not be implemented by bgpd)
71
72 set as-path prepend : Done
73 as-path tag : Not yet
74 automatic-tag : (This will not be implemented by bgpd)
75 community : Done
76 comm-list : Not yet
77 dampning : Not yet
78 default : (This will not be implemented by bgpd)
79 interface : (This will not be implemented by bgpd)
80 ip default : (This will not be implemented by bgpd)
81 ip next-hop : Done
82 ip precedence : (This will not be implemented by bgpd)
83 ip tos : (This will not be implemented by bgpd)
84 level : (This will not be implemented by bgpd)
85 local-preference : Done
86 metric : Done
87 metric-type : Not yet
88 origin : Done
89 tag : (This will not be implemented by bgpd)
90 weight : Done
Paul Jakma41367172007-08-06 15:24:51 +000091 pathlimit : Done
paul718e3742002-12-13 20:15:29 +000092
93o Local extention
94
95 set ipv6 next-hop global: Done
96 set ipv6 next-hop local : Done
Paul Jakma41367172007-08-06 15:24:51 +000097 set pathlimit ttl : Done
Denis Ovsienko841f7a52008-04-10 11:47:45 +000098 set as-path exclude : Done
Paul Jakma41367172007-08-06 15:24:51 +000099 match pathlimit as : Done
paul718e3742002-12-13 20:15:29 +0000100
101*/
102
Paul Jakma41367172007-08-06 15:24:51 +0000103/* Compiles either AS or TTL argument. It is amused the VTY code
104 * has already range-checked the values to be suitable as TTL or ASN
105 */
106static void *
107route_pathlimit_compile (const char *arg)
108{
109 unsigned long tmp;
110 u_int32_t *val;
111 char *endptr = NULL;
112
113 /* TTL or AS value shoud be integer. */
114 if (! all_digit (arg))
115 return NULL;
116
117 tmp = strtoul (arg, &endptr, 10);
118 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
119 return NULL;
120
121 if (!(val = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t))))
122 return NULL;
123
124 *val = tmp;
125
126 return val;
127}
128
129static void
130route_pathlimit_free (void *rule)
131{
132 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
133}
134
135static route_map_result_t
136route_match_pathlimit_as (void *rule, struct prefix *prefix, route_map_object_t type,
137 void *object)
138{
139 struct bgp_info *info = object;
140 struct attr *attr = info->attr;
141 uint32_t as = *(uint32_t *)rule;
142
143 if (type != RMAP_BGP)
144 return RMAP_NOMATCH;
145
146 if (!attr->pathlimit.as)
147 return RMAP_NOMATCH;
148
149 if (as == attr->pathlimit.as)
150 return RMAP_MATCH;
151
152 return RMAP_NOMATCH;
153}
154
155/* 'match pathlimit as' */
156struct route_map_rule_cmd route_match_pathlimit_as_cmd =
157{
158 "pathlimit as",
159 route_match_pathlimit_as,
160 route_pathlimit_compile,
161 route_pathlimit_free
162};
163
164/* Set pathlimit TTL. */
165static route_map_result_t
166route_set_pathlimit_ttl (void *rule, struct prefix *prefix,
167 route_map_object_t type, void *object)
168{
169 struct bgp_info *info = object;
170 struct attr *attr = info->attr;
171 u_char ttl = *(uint32_t *)rule;
172
173 if (type == RMAP_BGP)
174 {
175 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
176 attr->pathlimit.ttl = ttl;
177 attr->pathlimit.as = 0;
178 }
179
180 return RMAP_OKAY;
181}
182
183/* Set local preference rule structure. */
184struct route_map_rule_cmd route_set_pathlimit_ttl_cmd =
185{
186 "pathlimit ttl",
187 route_set_pathlimit_ttl,
188 route_pathlimit_compile,
189 route_pathlimit_free,
190};
191
paulfee0f4c2004-09-13 05:12:46 +0000192 /* 'match peer (A.B.C.D|X:X::X:X)' */
193
194/* Compares the peer specified in the 'match peer' clause with the peer
195 received in bgp_info->peer. If it is the same, or if the peer structure
196 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000197static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000198route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
199 void *object)
200{
201 union sockunion *su;
202 union sockunion *su2;
203 struct peer_group *group;
204 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000205 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000206
207 if (type == RMAP_BGP)
208 {
209 su = rule;
210 peer = ((struct bgp_info *) object)->peer;
211
212 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
213 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
214 return RMAP_NOMATCH;
215
216 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
217 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
218 su2 = sockunion_str2su ("0.0.0.0");
219 if ( sockunion_same (su, su2) )
220 {
paul22db9de2005-05-19 01:50:11 +0000221 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000222 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
223 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
224 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000225 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000226 else
paul22db9de2005-05-19 01:50:11 +0000227 ret = RMAP_NOMATCH;
228
229 sockunion_free (su2);
230 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000231 }
paul22db9de2005-05-19 01:50:11 +0000232 sockunion_free (su2);
233
paulfee0f4c2004-09-13 05:12:46 +0000234 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
235 {
236 if (sockunion_same (su, &peer->su))
237 return RMAP_MATCH;
238
239 return RMAP_NOMATCH;
240 }
241 else
242 {
243 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000244 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000245 {
246 if (sockunion_same (su, &peer->su))
247 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000248 }
Paul Jakma30a22312008-08-15 14:05:22 +0100249 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000250 }
251 }
252 return RMAP_NOMATCH;
253}
254
paul94f2b392005-06-28 12:44:16 +0000255static void *
paulfd79ac92004-10-13 05:06:08 +0000256route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000257{
258 union sockunion *su;
259 int ret;
260
261 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
262
263 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
264 if (ret < 0) {
265 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
266 return NULL;
267 }
268
269 return su;
270}
271
272/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000273static void
paulfee0f4c2004-09-13 05:12:46 +0000274route_match_peer_free (void *rule)
275{
276 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
277}
278
279/* Route map commands for ip address matching. */
280struct route_map_rule_cmd route_match_peer_cmd =
281{
282 "peer",
283 route_match_peer,
284 route_match_peer_compile,
285 route_match_peer_free
286};
287
paul718e3742002-12-13 20:15:29 +0000288/* `match ip address IP_ACCESS_LIST' */
289
290/* Match function should return 1 if match is success else return
291 zero. */
paul94f2b392005-06-28 12:44:16 +0000292static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000293route_match_ip_address (void *rule, struct prefix *prefix,
294 route_map_object_t type, void *object)
295{
296 struct access_list *alist;
297 /* struct prefix_ipv4 match; */
298
299 if (type == RMAP_BGP)
300 {
301 alist = access_list_lookup (AFI_IP, (char *) rule);
302 if (alist == NULL)
303 return RMAP_NOMATCH;
304
305 return (access_list_apply (alist, prefix) == FILTER_DENY ?
306 RMAP_NOMATCH : RMAP_MATCH);
307 }
308 return RMAP_NOMATCH;
309}
310
311/* Route map `ip address' match statement. `arg' should be
312 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000313static void *
paulfd79ac92004-10-13 05:06:08 +0000314route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000315{
316 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
317}
318
319/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000320static void
paul718e3742002-12-13 20:15:29 +0000321route_match_ip_address_free (void *rule)
322{
323 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
324}
325
326/* Route map commands for ip address matching. */
327struct route_map_rule_cmd route_match_ip_address_cmd =
328{
329 "ip address",
330 route_match_ip_address,
331 route_match_ip_address_compile,
332 route_match_ip_address_free
333};
334
335/* `match ip next-hop IP_ADDRESS' */
336
337/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000338static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000339route_match_ip_next_hop (void *rule, struct prefix *prefix,
340 route_map_object_t type, void *object)
341{
342 struct access_list *alist;
343 struct bgp_info *bgp_info;
344 struct prefix_ipv4 p;
345
346 if (type == RMAP_BGP)
347 {
348 bgp_info = object;
349 p.family = AF_INET;
350 p.prefix = bgp_info->attr->nexthop;
351 p.prefixlen = IPV4_MAX_BITLEN;
352
353 alist = access_list_lookup (AFI_IP, (char *) rule);
354 if (alist == NULL)
355 return RMAP_NOMATCH;
356
357 return (access_list_apply (alist, &p) == FILTER_DENY ?
358 RMAP_NOMATCH : RMAP_MATCH);
359 }
360 return RMAP_NOMATCH;
361}
362
363/* Route map `ip next-hop' match statement. `arg' is
364 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000365static void *
paulfd79ac92004-10-13 05:06:08 +0000366route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000367{
368 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
369}
370
371/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000372static void
paul718e3742002-12-13 20:15:29 +0000373route_match_ip_next_hop_free (void *rule)
374{
375 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
376}
377
378/* Route map commands for ip next-hop matching. */
379struct route_map_rule_cmd route_match_ip_next_hop_cmd =
380{
381 "ip next-hop",
382 route_match_ip_next_hop,
383 route_match_ip_next_hop_compile,
384 route_match_ip_next_hop_free
385};
386
hassoc1643bb2005-02-02 16:43:17 +0000387/* `match ip route-source ACCESS-LIST' */
388
389/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000390static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000391route_match_ip_route_source (void *rule, struct prefix *prefix,
392 route_map_object_t type, void *object)
393{
394 struct access_list *alist;
395 struct bgp_info *bgp_info;
396 struct peer *peer;
397 struct prefix_ipv4 p;
398
399 if (type == RMAP_BGP)
400 {
401 bgp_info = object;
402 peer = bgp_info->peer;
403
404 if (! peer || sockunion_family (&peer->su) != AF_INET)
405 return RMAP_NOMATCH;
406
407 p.family = AF_INET;
408 p.prefix = peer->su.sin.sin_addr;
409 p.prefixlen = IPV4_MAX_BITLEN;
410
411 alist = access_list_lookup (AFI_IP, (char *) rule);
412 if (alist == NULL)
413 return RMAP_NOMATCH;
414
415 return (access_list_apply (alist, &p) == FILTER_DENY ?
416 RMAP_NOMATCH : RMAP_MATCH);
417 }
418 return RMAP_NOMATCH;
419}
420
421/* Route map `ip route-source' match statement. `arg' is
422 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000423static void *
hassoc1643bb2005-02-02 16:43:17 +0000424route_match_ip_route_source_compile (const char *arg)
425{
426 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
427}
428
429/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000430static void
hassoc1643bb2005-02-02 16:43:17 +0000431route_match_ip_route_source_free (void *rule)
432{
433 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
434}
435
436/* Route map commands for ip route-source matching. */
437struct route_map_rule_cmd route_match_ip_route_source_cmd =
438{
439 "ip route-source",
440 route_match_ip_route_source,
441 route_match_ip_route_source_compile,
442 route_match_ip_route_source_free
443};
444
paul718e3742002-12-13 20:15:29 +0000445/* `match ip address prefix-list PREFIX_LIST' */
446
paul94f2b392005-06-28 12:44:16 +0000447static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000448route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
449 route_map_object_t type, void *object)
450{
451 struct prefix_list *plist;
452
453 if (type == RMAP_BGP)
454 {
455 plist = prefix_list_lookup (AFI_IP, (char *) rule);
456 if (plist == NULL)
457 return RMAP_NOMATCH;
458
459 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
460 RMAP_NOMATCH : RMAP_MATCH);
461 }
462 return RMAP_NOMATCH;
463}
464
paul94f2b392005-06-28 12:44:16 +0000465static void *
paulfd79ac92004-10-13 05:06:08 +0000466route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000467{
468 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
469}
470
paul94f2b392005-06-28 12:44:16 +0000471static void
paul718e3742002-12-13 20:15:29 +0000472route_match_ip_address_prefix_list_free (void *rule)
473{
474 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
475}
476
477struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
478{
479 "ip address prefix-list",
480 route_match_ip_address_prefix_list,
481 route_match_ip_address_prefix_list_compile,
482 route_match_ip_address_prefix_list_free
483};
484
485/* `match ip next-hop prefix-list PREFIX_LIST' */
486
paul94f2b392005-06-28 12:44:16 +0000487static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000488route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
489 route_map_object_t type, void *object)
490{
491 struct prefix_list *plist;
492 struct bgp_info *bgp_info;
493 struct prefix_ipv4 p;
494
495 if (type == RMAP_BGP)
496 {
497 bgp_info = object;
498 p.family = AF_INET;
499 p.prefix = bgp_info->attr->nexthop;
500 p.prefixlen = IPV4_MAX_BITLEN;
501
502 plist = prefix_list_lookup (AFI_IP, (char *) rule);
503 if (plist == NULL)
504 return RMAP_NOMATCH;
505
506 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
507 RMAP_NOMATCH : RMAP_MATCH);
508 }
509 return RMAP_NOMATCH;
510}
511
paul94f2b392005-06-28 12:44:16 +0000512static void *
paulfd79ac92004-10-13 05:06:08 +0000513route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000514{
515 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
516}
517
paul94f2b392005-06-28 12:44:16 +0000518static void
paul718e3742002-12-13 20:15:29 +0000519route_match_ip_next_hop_prefix_list_free (void *rule)
520{
521 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
522}
523
524struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
525{
526 "ip next-hop prefix-list",
527 route_match_ip_next_hop_prefix_list,
528 route_match_ip_next_hop_prefix_list_compile,
529 route_match_ip_next_hop_prefix_list_free
530};
531
hassoc1643bb2005-02-02 16:43:17 +0000532/* `match ip route-source prefix-list PREFIX_LIST' */
533
paul94f2b392005-06-28 12:44:16 +0000534static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000535route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
536 route_map_object_t type, void *object)
537{
538 struct prefix_list *plist;
539 struct bgp_info *bgp_info;
540 struct peer *peer;
541 struct prefix_ipv4 p;
542
543 if (type == RMAP_BGP)
544 {
545 bgp_info = object;
546 peer = bgp_info->peer;
547
548 if (! peer || sockunion_family (&peer->su) != AF_INET)
549 return RMAP_NOMATCH;
550
551 p.family = AF_INET;
552 p.prefix = peer->su.sin.sin_addr;
553 p.prefixlen = IPV4_MAX_BITLEN;
554
555 plist = prefix_list_lookup (AFI_IP, (char *) rule);
556 if (plist == NULL)
557 return RMAP_NOMATCH;
558
559 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
560 RMAP_NOMATCH : RMAP_MATCH);
561 }
562 return RMAP_NOMATCH;
563}
564
paul94f2b392005-06-28 12:44:16 +0000565static void *
hassoc1643bb2005-02-02 16:43:17 +0000566route_match_ip_route_source_prefix_list_compile (const char *arg)
567{
568 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
569}
570
paul94f2b392005-06-28 12:44:16 +0000571static void
hassoc1643bb2005-02-02 16:43:17 +0000572route_match_ip_route_source_prefix_list_free (void *rule)
573{
574 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
575}
576
577struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
578{
579 "ip route-source prefix-list",
580 route_match_ip_route_source_prefix_list,
581 route_match_ip_route_source_prefix_list_compile,
582 route_match_ip_route_source_prefix_list_free
583};
584
paul718e3742002-12-13 20:15:29 +0000585/* `match metric METRIC' */
586
587/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000588static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000589route_match_metric (void *rule, struct prefix *prefix,
590 route_map_object_t type, void *object)
591{
592 u_int32_t *med;
593 struct bgp_info *bgp_info;
594
595 if (type == RMAP_BGP)
596 {
597 med = rule;
598 bgp_info = object;
599
600 if (bgp_info->attr->med == *med)
601 return RMAP_MATCH;
602 else
603 return RMAP_NOMATCH;
604 }
605 return RMAP_NOMATCH;
606}
607
608/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000609static void *
paulfd79ac92004-10-13 05:06:08 +0000610route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000611{
612 u_int32_t *med;
613 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000614 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000615
paul3b424972003-10-13 09:47:32 +0000616 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000617 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000618 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000619
paul718e3742002-12-13 20:15:29 +0000620 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000621
622 if (!med)
623 return med;
624
paul3b424972003-10-13 09:47:32 +0000625 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000626 return med;
627}
628
629/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000630static void
paul718e3742002-12-13 20:15:29 +0000631route_match_metric_free (void *rule)
632{
633 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
634}
635
636/* Route map commands for metric matching. */
637struct route_map_rule_cmd route_match_metric_cmd =
638{
639 "metric",
640 route_match_metric,
641 route_match_metric_compile,
642 route_match_metric_free
643};
644
645/* `match as-path ASPATH' */
646
647/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000648static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000649route_match_aspath (void *rule, struct prefix *prefix,
650 route_map_object_t type, void *object)
651{
652
653 struct as_list *as_list;
654 struct bgp_info *bgp_info;
655
656 if (type == RMAP_BGP)
657 {
658 as_list = as_list_lookup ((char *) rule);
659 if (as_list == NULL)
660 return RMAP_NOMATCH;
661
662 bgp_info = object;
663
664 /* Perform match. */
665 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
666 }
667 return RMAP_NOMATCH;
668}
669
670/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000671static void *
paulfd79ac92004-10-13 05:06:08 +0000672route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000673{
674 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
675}
676
677/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000678static void
paul718e3742002-12-13 20:15:29 +0000679route_match_aspath_free (void *rule)
680{
681 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
682}
683
684/* Route map commands for aspath matching. */
685struct route_map_rule_cmd route_match_aspath_cmd =
686{
687 "as-path",
688 route_match_aspath,
689 route_match_aspath_compile,
690 route_match_aspath_free
691};
paul718e3742002-12-13 20:15:29 +0000692
693/* `match community COMMUNIY' */
694struct rmap_community
695{
696 char *name;
697 int exact;
698};
699
700/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000701static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000702route_match_community (void *rule, struct prefix *prefix,
703 route_map_object_t type, void *object)
704{
705 struct community_list *list;
706 struct bgp_info *bgp_info;
707 struct rmap_community *rcom;
708
709 if (type == RMAP_BGP)
710 {
711 bgp_info = object;
712 rcom = rule;
713
hassofee6e4e2005-02-02 16:29:31 +0000714 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000715 if (! list)
716 return RMAP_NOMATCH;
717
718 if (rcom->exact)
719 {
720 if (community_list_exact_match (bgp_info->attr->community, list))
721 return RMAP_MATCH;
722 }
723 else
724 {
725 if (community_list_match (bgp_info->attr->community, list))
726 return RMAP_MATCH;
727 }
728 }
729 return RMAP_NOMATCH;
730}
731
732/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000733static void *
paulfd79ac92004-10-13 05:06:08 +0000734route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000735{
736 struct rmap_community *rcom;
737 int len;
738 char *p;
739
740 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
741
742 p = strchr (arg, ' ');
743 if (p)
744 {
745 len = p - arg;
746 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
747 memcpy (rcom->name, arg, len);
748 rcom->exact = 1;
749 }
750 else
751 {
752 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
753 rcom->exact = 0;
754 }
755 return rcom;
756}
757
758/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000759static void
paul718e3742002-12-13 20:15:29 +0000760route_match_community_free (void *rule)
761{
762 struct rmap_community *rcom = rule;
763
764 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
765 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
766}
767
768/* Route map commands for community matching. */
769struct route_map_rule_cmd route_match_community_cmd =
770{
771 "community",
772 route_match_community,
773 route_match_community_compile,
774 route_match_community_free
775};
776
paul73ffb252003-04-19 15:49:49 +0000777/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000778static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000779route_match_ecommunity (void *rule, struct prefix *prefix,
780 route_map_object_t type, void *object)
781{
782 struct community_list *list;
783 struct bgp_info *bgp_info;
784
785 if (type == RMAP_BGP)
786 {
787 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000788
789 if (!bgp_info->attr->extra)
790 return RMAP_NOMATCH;
791
paul73ffb252003-04-19 15:49:49 +0000792 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000793 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000794 if (! list)
795 return RMAP_NOMATCH;
796
Paul Jakmafb982c22007-05-04 20:15:47 +0000797 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000798 return RMAP_MATCH;
799 }
800 return RMAP_NOMATCH;
801}
802
803/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000804static void *
paulfd79ac92004-10-13 05:06:08 +0000805route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000806{
807 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
808}
809
810/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000811static void
paul73ffb252003-04-19 15:49:49 +0000812route_match_ecommunity_free (void *rule)
813{
814 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
815}
816
817/* Route map commands for community matching. */
818struct route_map_rule_cmd route_match_ecommunity_cmd =
819{
820 "extcommunity",
821 route_match_ecommunity,
822 route_match_ecommunity_compile,
823 route_match_ecommunity_free
824};
825
paul718e3742002-12-13 20:15:29 +0000826/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
827 and `address-family vpnv4'. */
828
829/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000830static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000831route_match_origin (void *rule, struct prefix *prefix,
832 route_map_object_t type, void *object)
833{
834 u_char *origin;
835 struct bgp_info *bgp_info;
836
837 if (type == RMAP_BGP)
838 {
839 origin = rule;
840 bgp_info = object;
841
842 if (bgp_info->attr->origin == *origin)
843 return RMAP_MATCH;
844 }
845
846 return RMAP_NOMATCH;
847}
848
paul94f2b392005-06-28 12:44:16 +0000849static void *
paulfd79ac92004-10-13 05:06:08 +0000850route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000851{
852 u_char *origin;
853
854 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
855
856 if (strcmp (arg, "igp") == 0)
857 *origin = 0;
858 else if (strcmp (arg, "egp") == 0)
859 *origin = 1;
860 else
861 *origin = 2;
862
863 return origin;
864}
865
866/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000867static void
paul718e3742002-12-13 20:15:29 +0000868route_match_origin_free (void *rule)
869{
870 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
871}
872
873/* Route map commands for origin matching. */
874struct route_map_rule_cmd route_match_origin_cmd =
875{
876 "origin",
877 route_match_origin,
878 route_match_origin_compile,
879 route_match_origin_free
880};
881/* `set ip next-hop IP_ADDRESS' */
882
883/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000884struct rmap_ip_nexthop_set
885{
886 struct in_addr *address;
887 int peer_address;
888};
889
paul94f2b392005-06-28 12:44:16 +0000890static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000891route_set_ip_nexthop (void *rule, struct prefix *prefix,
892 route_map_object_t type, void *object)
893{
paulac41b2a2003-08-12 05:32:27 +0000894 struct rmap_ip_nexthop_set *rins = rule;
895 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000896 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000897 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000898
899 if (type == RMAP_BGP)
900 {
paul718e3742002-12-13 20:15:29 +0000901 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000902 peer = bgp_info->peer;
903
904 if (rins->peer_address)
905 {
paulfee0f4c2004-09-13 05:12:46 +0000906 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
907 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000908 && peer->su_remote
909 && sockunion_family (peer->su_remote) == AF_INET)
910 {
911 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
912 bgp_info->attr->nexthop = peer_address;
913 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
914 }
915 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
916 && peer->su_local
917 && sockunion_family (peer->su_local) == AF_INET)
918 {
919 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
920 bgp_info->attr->nexthop = peer_address;
921 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
922 }
923 }
924 else
925 {
926 /* Set next hop value. */
927 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
928 bgp_info->attr->nexthop = *rins->address;
929 }
paul718e3742002-12-13 20:15:29 +0000930 }
931
932 return RMAP_OKAY;
933}
934
935/* Route map `ip nexthop' compile function. Given string is converted
936 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000937static void *
paulfd79ac92004-10-13 05:06:08 +0000938route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000939{
paulac41b2a2003-08-12 05:32:27 +0000940 struct rmap_ip_nexthop_set *rins;
941 struct in_addr *address = NULL;
942 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000943 int ret;
paul718e3742002-12-13 20:15:29 +0000944
paulac41b2a2003-08-12 05:32:27 +0000945 if (strcmp (arg, "peer-address") == 0)
946 peer_address = 1;
947 else
paul718e3742002-12-13 20:15:29 +0000948 {
paulac41b2a2003-08-12 05:32:27 +0000949 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
950 ret = inet_aton (arg, address);
951
952 if (ret == 0)
953 {
954 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
955 return NULL;
956 }
paul718e3742002-12-13 20:15:29 +0000957 }
958
Stephen Hemminger393deb92008-08-18 14:13:29 -0700959 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000960
961 rins->address = address;
962 rins->peer_address = peer_address;
963
964 return rins;
paul718e3742002-12-13 20:15:29 +0000965}
966
967/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000968static void
paul718e3742002-12-13 20:15:29 +0000969route_set_ip_nexthop_free (void *rule)
970{
paulac41b2a2003-08-12 05:32:27 +0000971 struct rmap_ip_nexthop_set *rins = rule;
972
973 if (rins->address)
974 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
975
976 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000977}
978
979/* Route map commands for ip nexthop set. */
980struct route_map_rule_cmd route_set_ip_nexthop_cmd =
981{
982 "ip next-hop",
983 route_set_ip_nexthop,
984 route_set_ip_nexthop_compile,
985 route_set_ip_nexthop_free
986};
987
988/* `set local-preference LOCAL_PREF' */
989
990/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000991static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000992route_set_local_pref (void *rule, struct prefix *prefix,
993 route_map_object_t type, void *object)
994{
995 u_int32_t *local_pref;
996 struct bgp_info *bgp_info;
997
998 if (type == RMAP_BGP)
999 {
1000 /* Fetch routemap's rule information. */
1001 local_pref = rule;
1002 bgp_info = object;
1003
1004 /* Set local preference value. */
1005 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1006 bgp_info->attr->local_pref = *local_pref;
1007 }
1008
1009 return RMAP_OKAY;
1010}
1011
1012/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001013static void *
paulfd79ac92004-10-13 05:06:08 +00001014route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001015{
paulfd79ac92004-10-13 05:06:08 +00001016 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001017 u_int32_t *local_pref;
1018 char *endptr = NULL;
1019
1020 /* Local preference value shoud be integer. */
1021 if (! all_digit (arg))
1022 return NULL;
paulfd79ac92004-10-13 05:06:08 +00001023
1024 tmp = strtoul (arg, &endptr, 10);
1025 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1026 return NULL;
1027
1028 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1029
1030 if (!local_pref)
1031 return local_pref;
1032
1033 *local_pref = tmp;
1034
paul718e3742002-12-13 20:15:29 +00001035 return local_pref;
1036}
1037
1038/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001039static void
paul718e3742002-12-13 20:15:29 +00001040route_set_local_pref_free (void *rule)
1041{
1042 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1043}
1044
1045/* Set local preference rule structure. */
1046struct route_map_rule_cmd route_set_local_pref_cmd =
1047{
1048 "local-preference",
1049 route_set_local_pref,
1050 route_set_local_pref_compile,
1051 route_set_local_pref_free,
1052};
1053
1054/* `set weight WEIGHT' */
1055
1056/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001057static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001058route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1059 void *object)
1060{
1061 u_int32_t *weight;
1062 struct bgp_info *bgp_info;
1063
1064 if (type == RMAP_BGP)
1065 {
1066 /* Fetch routemap's rule information. */
1067 weight = rule;
1068 bgp_info = object;
1069
1070 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001071 if (*weight)
1072 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1073 else if (bgp_info->attr->extra)
1074 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001075 }
1076
1077 return RMAP_OKAY;
1078}
1079
1080/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001081static void *
paulfd79ac92004-10-13 05:06:08 +00001082route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001083{
paulfd79ac92004-10-13 05:06:08 +00001084 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001085 u_int32_t *weight;
1086 char *endptr = NULL;
1087
1088 /* Local preference value shoud be integer. */
1089 if (! all_digit (arg))
1090 return NULL;
1091
paulfd79ac92004-10-13 05:06:08 +00001092
1093 tmp = strtoul (arg, &endptr, 10);
1094 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1095 return NULL;
1096
paul718e3742002-12-13 20:15:29 +00001097 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001098
1099 if (weight == NULL)
1100 return weight;
1101
1102 *weight = tmp;
1103
paul718e3742002-12-13 20:15:29 +00001104 return weight;
1105}
1106
1107/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001108static void
paul718e3742002-12-13 20:15:29 +00001109route_set_weight_free (void *rule)
1110{
1111 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1112}
1113
1114/* Set local preference rule structure. */
1115struct route_map_rule_cmd route_set_weight_cmd =
1116{
1117 "weight",
1118 route_set_weight,
1119 route_set_weight_compile,
1120 route_set_weight_free,
1121};
1122
1123/* `set metric METRIC' */
1124
1125/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001126static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001127route_set_metric (void *rule, struct prefix *prefix,
1128 route_map_object_t type, void *object)
1129{
1130 char *metric;
1131 u_int32_t metric_val;
1132 struct bgp_info *bgp_info;
1133
1134 if (type == RMAP_BGP)
1135 {
1136 /* Fetch routemap's rule information. */
1137 metric = rule;
1138 bgp_info = object;
1139
1140 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1141 bgp_info->attr->med = 0;
1142 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1143
1144 if (all_digit (metric))
1145 {
1146 metric_val = strtoul (metric, (char **)NULL, 10);
1147 bgp_info->attr->med = metric_val;
1148 }
1149 else
1150 {
1151 metric_val = strtoul (metric+1, (char **)NULL, 10);
1152
1153 if (strncmp (metric, "+", 1) == 0)
1154 {
paul3b424972003-10-13 09:47:32 +00001155 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1156 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001157 else
paul537d8ea2003-08-27 06:45:32 +00001158 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001159 }
1160 else if (strncmp (metric, "-", 1) == 0)
1161 {
paul537d8ea2003-08-27 06:45:32 +00001162 if (bgp_info->attr->med <= metric_val)
1163 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001164 else
paul537d8ea2003-08-27 06:45:32 +00001165 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001166 }
1167 }
1168 }
1169 return RMAP_OKAY;
1170}
1171
1172/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001173static void *
paulfd79ac92004-10-13 05:06:08 +00001174route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001175{
1176 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001177 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001178 char *endptr = NULL;
1179
1180 if (all_digit (arg))
1181 {
1182 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001183 larg = strtoul (arg, &endptr, 10);
1184 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001185 return NULL;
paul94f2b392005-06-28 12:44:16 +00001186 metric = larg;
paul718e3742002-12-13 20:15:29 +00001187 }
1188 else
1189 {
1190 /* set metric +/-value check */
1191 if ((strncmp (arg, "+", 1) != 0
1192 && strncmp (arg, "-", 1) != 0)
1193 || (! all_digit (arg+1)))
1194 return NULL;
1195
paul94f2b392005-06-28 12:44:16 +00001196 larg = strtoul (arg+1, &endptr, 10);
1197 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001198 return NULL;
paul94f2b392005-06-28 12:44:16 +00001199 metric = larg;
paul718e3742002-12-13 20:15:29 +00001200 }
1201
1202 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1203}
1204
1205/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001206static void
paul718e3742002-12-13 20:15:29 +00001207route_set_metric_free (void *rule)
1208{
1209 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1210}
1211
1212/* Set metric rule structure. */
1213struct route_map_rule_cmd route_set_metric_cmd =
1214{
1215 "metric",
1216 route_set_metric,
1217 route_set_metric_compile,
1218 route_set_metric_free,
1219};
1220
1221/* `set as-path prepend ASPATH' */
1222
1223/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001224static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001225route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1226{
1227 struct aspath *aspath;
1228 struct aspath *new;
1229 struct bgp_info *binfo;
1230
1231 if (type == RMAP_BGP)
1232 {
1233 aspath = rule;
1234 binfo = object;
1235
1236 if (binfo->attr->aspath->refcnt)
1237 new = aspath_dup (binfo->attr->aspath);
1238 else
1239 new = binfo->attr->aspath;
1240
1241 aspath_prepend (aspath, new);
1242 binfo->attr->aspath = new;
1243 }
1244
1245 return RMAP_OKAY;
1246}
1247
1248/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001249static void *
paulfd79ac92004-10-13 05:06:08 +00001250route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001251{
1252 struct aspath *aspath;
1253
1254 aspath = aspath_str2aspath (arg);
1255 if (! aspath)
1256 return NULL;
1257 return aspath;
1258}
1259
1260/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001261static void
paul718e3742002-12-13 20:15:29 +00001262route_set_aspath_prepend_free (void *rule)
1263{
1264 struct aspath *aspath = rule;
1265 aspath_free (aspath);
1266}
1267
1268/* Set metric rule structure. */
1269struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1270{
1271 "as-path prepend",
1272 route_set_aspath_prepend,
1273 route_set_aspath_prepend_compile,
1274 route_set_aspath_prepend_free,
1275};
1276
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001277/* `set as-path exclude ASn' */
1278
1279/* For ASN exclude mechanism.
1280 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1281 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1282 */
1283static route_map_result_t
1284route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1285{
1286 struct aspath * new_path, * exclude_path;
1287 struct bgp_info *binfo;
1288
1289 if (type == RMAP_BGP)
1290 {
1291 exclude_path = rule;
1292 binfo = object;
1293 if (binfo->attr->aspath->refcnt)
1294 new_path = aspath_dup (binfo->attr->aspath);
1295 else
1296 new_path = binfo->attr->aspath;
1297 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1298 }
1299 return RMAP_OKAY;
1300}
1301
1302/* FIXME: consider using route_set_aspath_prepend_compile() and
1303 * route_set_aspath_prepend_free(), which two below function are
1304 * exact clones of.
1305 */
1306
1307/* Compile function for as-path exclude. */
1308static void *
1309route_set_aspath_exclude_compile (const char *arg)
1310{
1311 struct aspath *aspath;
1312
1313 aspath = aspath_str2aspath (arg);
1314 if (! aspath)
1315 return NULL;
1316 return aspath;
1317}
1318
1319static void
1320route_set_aspath_exclude_free (void *rule)
1321{
1322 struct aspath *aspath = rule;
1323 aspath_free (aspath);
1324}
1325
1326/* Set ASn exlude rule structure. */
1327struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1328{
1329 "as-path exclude",
1330 route_set_aspath_exclude,
1331 route_set_aspath_exclude_compile,
1332 route_set_aspath_exclude_free,
1333};
1334
paul718e3742002-12-13 20:15:29 +00001335/* `set community COMMUNITY' */
1336struct rmap_com_set
1337{
1338 struct community *com;
1339 int additive;
1340 int none;
1341};
1342
1343/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001344static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001345route_set_community (void *rule, struct prefix *prefix,
1346 route_map_object_t type, void *object)
1347{
1348 struct rmap_com_set *rcs;
1349 struct bgp_info *binfo;
1350 struct attr *attr;
1351 struct community *new = NULL;
1352 struct community *old;
1353 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001354
paul718e3742002-12-13 20:15:29 +00001355 if (type == RMAP_BGP)
1356 {
1357 rcs = rule;
1358 binfo = object;
1359 attr = binfo->attr;
1360 old = attr->community;
1361
1362 /* "none" case. */
1363 if (rcs->none)
1364 {
1365 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1366 attr->community = NULL;
1367 return RMAP_OKAY;
1368 }
1369
1370 /* "additive" case. */
1371 if (rcs->additive && old)
1372 {
1373 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001374
1375 /* HACK: if the old community is not intern'd,
1376 * we should free it here, or all reference to it may be lost.
1377 * Really need to cleanup attribute caching sometime.
1378 */
1379 if (old->refcnt == 0)
1380 community_free (old);
paul718e3742002-12-13 20:15:29 +00001381 new = community_uniq_sort (merge);
1382 community_free (merge);
1383 }
1384 else
1385 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001386
1387 /* will be interned by caller if required */
paul718e3742002-12-13 20:15:29 +00001388 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001389
paul718e3742002-12-13 20:15:29 +00001390 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1391 }
1392
1393 return RMAP_OKAY;
1394}
1395
1396/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001397static void *
paulfd79ac92004-10-13 05:06:08 +00001398route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001399{
1400 struct rmap_com_set *rcs;
1401 struct community *com = NULL;
1402 char *sp;
1403 int additive = 0;
1404 int none = 0;
1405
1406 if (strcmp (arg, "none") == 0)
1407 none = 1;
1408 else
1409 {
1410 sp = strstr (arg, "additive");
1411
1412 if (sp && sp > arg)
1413 {
1414 /* "additive" keyworkd is included. */
1415 additive = 1;
1416 *(sp - 1) = '\0';
1417 }
1418
1419 com = community_str2com (arg);
1420
1421 if (additive)
1422 *(sp - 1) = ' ';
1423
1424 if (! com)
1425 return NULL;
1426 }
1427
Stephen Hemminger393deb92008-08-18 14:13:29 -07001428 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
paul718e3742002-12-13 20:15:29 +00001429 rcs->com = com;
1430 rcs->additive = additive;
1431 rcs->none = none;
1432
1433 return rcs;
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_free (void *rule)
1439{
1440 struct rmap_com_set *rcs = rule;
1441
1442 if (rcs->com)
1443 community_free (rcs->com);
1444 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1445}
1446
1447/* Set community rule structure. */
1448struct route_map_rule_cmd route_set_community_cmd =
1449{
1450 "community",
1451 route_set_community,
1452 route_set_community_compile,
1453 route_set_community_free,
1454};
1455
hassofee6e4e2005-02-02 16:29:31 +00001456/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001457
1458/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001459static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001460route_set_community_delete (void *rule, struct prefix *prefix,
1461 route_map_object_t type, void *object)
1462{
1463 struct community_list *list;
1464 struct community *merge;
1465 struct community *new;
1466 struct community *old;
1467 struct bgp_info *binfo;
1468
1469 if (type == RMAP_BGP)
1470 {
1471 if (! rule)
1472 return RMAP_OKAY;
1473
1474 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001475 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001476 old = binfo->attr->community;
1477
1478 if (list && old)
1479 {
1480 merge = community_list_match_delete (community_dup (old), list);
1481 new = community_uniq_sort (merge);
1482 community_free (merge);
1483
1484 if (new->size == 0)
1485 {
1486 binfo->attr->community = NULL;
1487 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1488 community_free (new);
1489 }
1490 else
1491 {
1492 binfo->attr->community = new;
1493 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1494 }
1495 }
1496 }
1497
1498 return RMAP_OKAY;
1499}
1500
1501/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001502static void *
paulfd79ac92004-10-13 05:06:08 +00001503route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001504{
1505 char *p;
1506 char *str;
1507 int len;
1508
1509 p = strchr (arg, ' ');
1510 if (p)
1511 {
1512 len = p - arg;
1513 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1514 memcpy (str, arg, len);
1515 }
1516 else
1517 str = NULL;
1518
1519 return str;
1520}
1521
1522/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001523static void
paul718e3742002-12-13 20:15:29 +00001524route_set_community_delete_free (void *rule)
1525{
1526 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1527}
1528
1529/* Set community rule structure. */
1530struct route_map_rule_cmd route_set_community_delete_cmd =
1531{
1532 "comm-list",
1533 route_set_community_delete,
1534 route_set_community_delete_compile,
1535 route_set_community_delete_free,
1536};
1537
1538/* `set extcommunity rt COMMUNITY' */
1539
1540/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001541static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001542route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1543 route_map_object_t type, void *object)
1544{
1545 struct ecommunity *ecom;
1546 struct ecommunity *new_ecom;
1547 struct ecommunity *old_ecom;
1548 struct bgp_info *bgp_info;
1549
1550 if (type == RMAP_BGP)
1551 {
1552 ecom = rule;
1553 bgp_info = object;
1554
1555 if (! ecom)
1556 return RMAP_OKAY;
1557
1558 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001559 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001560
1561 if (old_ecom)
1562 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1563 else
1564 new_ecom = ecommunity_dup (ecom);
1565
Paul Jakmafb982c22007-05-04 20:15:47 +00001566 bgp_info->attr->extra->ecommunity = new_ecom;
paul718e3742002-12-13 20:15:29 +00001567
hasso70601e02005-05-27 03:26:57 +00001568 if (old_ecom)
1569 ecommunity_free (old_ecom);
1570
paul718e3742002-12-13 20:15:29 +00001571 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1572 }
1573 return RMAP_OKAY;
1574}
1575
1576/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001577static void *
paulfd79ac92004-10-13 05:06:08 +00001578route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001579{
1580 struct ecommunity *ecom;
1581
1582 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1583 if (! ecom)
1584 return NULL;
1585 return ecom;
1586}
1587
1588/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001589static void
paul718e3742002-12-13 20:15:29 +00001590route_set_ecommunity_rt_free (void *rule)
1591{
1592 struct ecommunity *ecom = rule;
1593 ecommunity_free (ecom);
1594}
1595
1596/* Set community rule structure. */
1597struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1598{
1599 "extcommunity rt",
1600 route_set_ecommunity_rt,
1601 route_set_ecommunity_rt_compile,
1602 route_set_ecommunity_rt_free,
1603};
1604
1605/* `set extcommunity soo COMMUNITY' */
1606
1607/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001608static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001609route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1610 route_map_object_t type, void *object)
1611{
1612 struct ecommunity *ecom;
1613 struct bgp_info *bgp_info;
1614
1615 if (type == RMAP_BGP)
1616 {
1617 ecom = rule;
1618 bgp_info = object;
1619
1620 if (! ecom)
1621 return RMAP_OKAY;
1622
1623 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
Paul Jakmafb982c22007-05-04 20:15:47 +00001624 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
paul718e3742002-12-13 20:15:29 +00001625 }
1626 return RMAP_OKAY;
1627}
1628
1629/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001630static void *
paulfd79ac92004-10-13 05:06:08 +00001631route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001632{
1633 struct ecommunity *ecom;
1634
1635 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1636 if (! ecom)
1637 return NULL;
1638
1639 return ecom;
1640}
1641
1642/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001643static void
paul718e3742002-12-13 20:15:29 +00001644route_set_ecommunity_soo_free (void *rule)
1645{
1646 struct ecommunity *ecom = rule;
1647 ecommunity_free (ecom);
1648}
1649
1650/* Set community rule structure. */
1651struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1652{
1653 "extcommunity soo",
1654 route_set_ecommunity_soo,
1655 route_set_ecommunity_soo_compile,
1656 route_set_ecommunity_soo_free,
1657};
1658
1659/* `set origin ORIGIN' */
1660
1661/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001662static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001663route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1664{
1665 u_char *origin;
1666 struct bgp_info *bgp_info;
1667
1668 if (type == RMAP_BGP)
1669 {
1670 origin = rule;
1671 bgp_info = object;
1672
1673 bgp_info->attr->origin = *origin;
1674 }
1675
1676 return RMAP_OKAY;
1677}
1678
1679/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001680static void *
paulfd79ac92004-10-13 05:06:08 +00001681route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001682{
1683 u_char *origin;
1684
1685 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1686
1687 if (strcmp (arg, "igp") == 0)
1688 *origin = 0;
1689 else if (strcmp (arg, "egp") == 0)
1690 *origin = 1;
1691 else
1692 *origin = 2;
1693
1694 return origin;
1695}
1696
1697/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001698static void
paul718e3742002-12-13 20:15:29 +00001699route_set_origin_free (void *rule)
1700{
1701 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1702}
1703
1704/* Set metric rule structure. */
1705struct route_map_rule_cmd route_set_origin_cmd =
1706{
1707 "origin",
1708 route_set_origin,
1709 route_set_origin_compile,
1710 route_set_origin_free,
1711};
1712
1713/* `set atomic-aggregate' */
1714
1715/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001716static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001717route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1718 route_map_object_t type, void *object)
1719{
1720 struct bgp_info *bgp_info;
1721
1722 if (type == RMAP_BGP)
1723 {
1724 bgp_info = object;
1725 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1726 }
1727
1728 return RMAP_OKAY;
1729}
1730
1731/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001732static void *
paulfd79ac92004-10-13 05:06:08 +00001733route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001734{
1735 return (void *)1;
1736}
1737
1738/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001739static void
paul718e3742002-12-13 20:15:29 +00001740route_set_atomic_aggregate_free (void *rule)
1741{
1742 return;
1743}
1744
1745/* Set atomic aggregate rule structure. */
1746struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1747{
1748 "atomic-aggregate",
1749 route_set_atomic_aggregate,
1750 route_set_atomic_aggregate_compile,
1751 route_set_atomic_aggregate_free,
1752};
1753
1754/* `set aggregator as AS A.B.C.D' */
1755struct aggregator
1756{
1757 as_t as;
1758 struct in_addr address;
1759};
1760
paul94f2b392005-06-28 12:44:16 +00001761static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001762route_set_aggregator_as (void *rule, struct prefix *prefix,
1763 route_map_object_t type, void *object)
1764{
1765 struct bgp_info *bgp_info;
1766 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001767 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001768
1769 if (type == RMAP_BGP)
1770 {
1771 bgp_info = object;
1772 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001773 ae = bgp_attr_extra_get (bgp_info->attr);
1774
1775 ae->aggregator_as = aggregator->as;
1776 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001777 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1778 }
1779
1780 return RMAP_OKAY;
1781}
1782
paul94f2b392005-06-28 12:44:16 +00001783static void *
paulfd79ac92004-10-13 05:06:08 +00001784route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001785{
1786 struct aggregator *aggregator;
1787 char as[10];
1788 char address[20];
1789
Stephen Hemminger393deb92008-08-18 14:13:29 -07001790 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001791 sscanf (arg, "%s %s", as, address);
1792
1793 aggregator->as = strtoul (as, NULL, 10);
1794 inet_aton (address, &aggregator->address);
1795
1796 return aggregator;
1797}
1798
paul94f2b392005-06-28 12:44:16 +00001799static void
paul718e3742002-12-13 20:15:29 +00001800route_set_aggregator_as_free (void *rule)
1801{
1802 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1803}
1804
1805struct route_map_rule_cmd route_set_aggregator_as_cmd =
1806{
1807 "aggregator as",
1808 route_set_aggregator_as,
1809 route_set_aggregator_as_compile,
1810 route_set_aggregator_as_free,
1811};
1812
1813#ifdef HAVE_IPV6
1814/* `match ipv6 address IP_ACCESS_LIST' */
1815
paul94f2b392005-06-28 12:44:16 +00001816static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001817route_match_ipv6_address (void *rule, struct prefix *prefix,
1818 route_map_object_t type, void *object)
1819{
1820 struct access_list *alist;
1821
1822 if (type == RMAP_BGP)
1823 {
1824 alist = access_list_lookup (AFI_IP6, (char *) rule);
1825 if (alist == NULL)
1826 return RMAP_NOMATCH;
1827
1828 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1829 RMAP_NOMATCH : RMAP_MATCH);
1830 }
1831 return RMAP_NOMATCH;
1832}
1833
paul94f2b392005-06-28 12:44:16 +00001834static void *
paulfd79ac92004-10-13 05:06:08 +00001835route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001836{
1837 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1838}
1839
paul94f2b392005-06-28 12:44:16 +00001840static void
paul718e3742002-12-13 20:15:29 +00001841route_match_ipv6_address_free (void *rule)
1842{
1843 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1844}
1845
1846/* Route map commands for ip address matching. */
1847struct route_map_rule_cmd route_match_ipv6_address_cmd =
1848{
1849 "ipv6 address",
1850 route_match_ipv6_address,
1851 route_match_ipv6_address_compile,
1852 route_match_ipv6_address_free
1853};
1854
1855/* `match ipv6 next-hop IP_ADDRESS' */
1856
paul94f2b392005-06-28 12:44:16 +00001857static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001858route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1859 route_map_object_t type, void *object)
1860{
1861 struct in6_addr *addr;
1862 struct bgp_info *bgp_info;
1863
1864 if (type == RMAP_BGP)
1865 {
1866 addr = rule;
1867 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001868
1869 if (!bgp_info->attr->extra)
1870 return RMAP_NOMATCH;
1871
1872 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001873 return RMAP_MATCH;
1874
Paul Jakmafb982c22007-05-04 20:15:47 +00001875 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1876 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001877 return RMAP_MATCH;
1878
1879 return RMAP_NOMATCH;
1880 }
1881
1882 return RMAP_NOMATCH;
1883}
1884
paul94f2b392005-06-28 12:44:16 +00001885static void *
paulfd79ac92004-10-13 05:06:08 +00001886route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001887{
1888 struct in6_addr *address;
1889 int ret;
1890
1891 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1892
1893 ret = inet_pton (AF_INET6, arg, address);
1894 if (!ret)
1895 {
1896 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1897 return NULL;
1898 }
1899
1900 return address;
1901}
1902
paul94f2b392005-06-28 12:44:16 +00001903static void
paul718e3742002-12-13 20:15:29 +00001904route_match_ipv6_next_hop_free (void *rule)
1905{
1906 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1907}
1908
1909struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1910{
1911 "ipv6 next-hop",
1912 route_match_ipv6_next_hop,
1913 route_match_ipv6_next_hop_compile,
1914 route_match_ipv6_next_hop_free
1915};
1916
1917/* `match ipv6 address prefix-list PREFIX_LIST' */
1918
paul94f2b392005-06-28 12:44:16 +00001919static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001920route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1921 route_map_object_t type, void *object)
1922{
1923 struct prefix_list *plist;
1924
1925 if (type == RMAP_BGP)
1926 {
1927 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1928 if (plist == NULL)
1929 return RMAP_NOMATCH;
1930
1931 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1932 RMAP_NOMATCH : RMAP_MATCH);
1933 }
1934 return RMAP_NOMATCH;
1935}
1936
paul94f2b392005-06-28 12:44:16 +00001937static void *
paulfd79ac92004-10-13 05:06:08 +00001938route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001939{
1940 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1941}
1942
paul94f2b392005-06-28 12:44:16 +00001943static void
paul718e3742002-12-13 20:15:29 +00001944route_match_ipv6_address_prefix_list_free (void *rule)
1945{
1946 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1947}
1948
1949struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1950{
1951 "ipv6 address prefix-list",
1952 route_match_ipv6_address_prefix_list,
1953 route_match_ipv6_address_prefix_list_compile,
1954 route_match_ipv6_address_prefix_list_free
1955};
1956
1957/* `set ipv6 nexthop global IP_ADDRESS' */
1958
1959/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001960static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001961route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1962 route_map_object_t type, void *object)
1963{
1964 struct in6_addr *address;
1965 struct bgp_info *bgp_info;
1966
1967 if (type == RMAP_BGP)
1968 {
1969 /* Fetch routemap's rule information. */
1970 address = rule;
1971 bgp_info = object;
1972
1973 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001974 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001975
1976 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001977 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1978 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001979 }
1980
1981 return RMAP_OKAY;
1982}
1983
1984/* Route map `ip next-hop' compile function. Given string is converted
1985 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001986static void *
paulfd79ac92004-10-13 05:06:08 +00001987route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001988{
1989 int ret;
1990 struct in6_addr *address;
1991
1992 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1993
1994 ret = inet_pton (AF_INET6, arg, address);
1995
1996 if (ret == 0)
1997 {
1998 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1999 return NULL;
2000 }
2001
2002 return address;
2003}
2004
2005/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002006static void
paul718e3742002-12-13 20:15:29 +00002007route_set_ipv6_nexthop_global_free (void *rule)
2008{
2009 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2010}
2011
2012/* Route map commands for ip nexthop set. */
2013struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2014{
2015 "ipv6 next-hop global",
2016 route_set_ipv6_nexthop_global,
2017 route_set_ipv6_nexthop_global_compile,
2018 route_set_ipv6_nexthop_global_free
2019};
2020
2021/* `set ipv6 nexthop local IP_ADDRESS' */
2022
2023/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002024static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002025route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2026 route_map_object_t type, void *object)
2027{
2028 struct in6_addr *address;
2029 struct bgp_info *bgp_info;
2030
2031 if (type == RMAP_BGP)
2032 {
2033 /* Fetch routemap's rule information. */
2034 address = rule;
2035 bgp_info = object;
2036
2037 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002038 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002039
2040 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002041 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2042 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002043 }
2044
2045 return RMAP_OKAY;
2046}
2047
2048/* Route map `ip nexthop' compile function. Given string is converted
2049 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002050static void *
paulfd79ac92004-10-13 05:06:08 +00002051route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002052{
2053 int ret;
2054 struct in6_addr *address;
2055
2056 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2057
2058 ret = inet_pton (AF_INET6, arg, address);
2059
2060 if (ret == 0)
2061 {
2062 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2063 return NULL;
2064 }
2065
2066 return address;
2067}
2068
2069/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002070static void
paul718e3742002-12-13 20:15:29 +00002071route_set_ipv6_nexthop_local_free (void *rule)
2072{
2073 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2074}
2075
2076/* Route map commands for ip nexthop set. */
2077struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2078{
2079 "ipv6 next-hop local",
2080 route_set_ipv6_nexthop_local,
2081 route_set_ipv6_nexthop_local_compile,
2082 route_set_ipv6_nexthop_local_free
2083};
2084#endif /* HAVE_IPV6 */
2085
2086/* `set vpnv4 nexthop A.B.C.D' */
2087
paul94f2b392005-06-28 12:44:16 +00002088static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002089route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2090 route_map_object_t type, void *object)
2091{
2092 struct in_addr *address;
2093 struct bgp_info *bgp_info;
2094
2095 if (type == RMAP_BGP)
2096 {
2097 /* Fetch routemap's rule information. */
2098 address = rule;
2099 bgp_info = object;
2100
2101 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002102 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002103 }
2104
2105 return RMAP_OKAY;
2106}
2107
paul94f2b392005-06-28 12:44:16 +00002108static void *
paulfd79ac92004-10-13 05:06:08 +00002109route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002110{
2111 int ret;
2112 struct in_addr *address;
2113
2114 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2115
2116 ret = inet_aton (arg, address);
2117
2118 if (ret == 0)
2119 {
2120 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2121 return NULL;
2122 }
2123
2124 return address;
2125}
2126
paul94f2b392005-06-28 12:44:16 +00002127static void
paul718e3742002-12-13 20:15:29 +00002128route_set_vpnv4_nexthop_free (void *rule)
2129{
2130 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2131}
2132
2133/* Route map commands for ip nexthop set. */
2134struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2135{
2136 "vpnv4 next-hop",
2137 route_set_vpnv4_nexthop,
2138 route_set_vpnv4_nexthop_compile,
2139 route_set_vpnv4_nexthop_free
2140};
2141
2142/* `set originator-id' */
2143
2144/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002145static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002146route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2147{
2148 struct in_addr *address;
2149 struct bgp_info *bgp_info;
2150
2151 if (type == RMAP_BGP)
2152 {
2153 address = rule;
2154 bgp_info = object;
2155
2156 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002157 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002158 }
2159
2160 return RMAP_OKAY;
2161}
2162
2163/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002164static void *
paulfd79ac92004-10-13 05:06:08 +00002165route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002166{
2167 int ret;
2168 struct in_addr *address;
2169
2170 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2171
2172 ret = inet_aton (arg, address);
2173
2174 if (ret == 0)
2175 {
2176 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2177 return NULL;
2178 }
2179
2180 return address;
2181}
2182
2183/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002184static void
paul718e3742002-12-13 20:15:29 +00002185route_set_originator_id_free (void *rule)
2186{
2187 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2188}
2189
2190/* Set metric rule structure. */
2191struct route_map_rule_cmd route_set_originator_id_cmd =
2192{
2193 "originator-id",
2194 route_set_originator_id,
2195 route_set_originator_id_compile,
2196 route_set_originator_id_free,
2197};
2198
2199/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002200static int
paul718e3742002-12-13 20:15:29 +00002201bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002202 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002203{
2204 int ret;
2205
2206 ret = route_map_add_match (index, command, arg);
2207 if (ret)
2208 {
2209 switch (ret)
2210 {
2211 case RMAP_RULE_MISSING:
2212 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2213 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002214 case RMAP_COMPILE_ERROR:
2215 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2216 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002217 }
2218 }
2219 return CMD_SUCCESS;
2220}
2221
2222/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002223static int
paul718e3742002-12-13 20:15:29 +00002224bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002225 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002226{
2227 int ret;
2228
2229 ret = route_map_delete_match (index, command, arg);
2230 if (ret)
2231 {
2232 switch (ret)
2233 {
2234 case RMAP_RULE_MISSING:
2235 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2236 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002237 case RMAP_COMPILE_ERROR:
2238 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2239 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002240 }
2241 }
2242 return CMD_SUCCESS;
2243}
2244
2245/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002246static int
paul718e3742002-12-13 20:15:29 +00002247bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002248 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002249{
2250 int ret;
2251
2252 ret = route_map_add_set (index, command, arg);
2253 if (ret)
2254 {
2255 switch (ret)
2256 {
2257 case RMAP_RULE_MISSING:
2258 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2259 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002260 case RMAP_COMPILE_ERROR:
2261 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2262 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002263 }
2264 }
2265 return CMD_SUCCESS;
2266}
2267
2268/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002269static int
paul718e3742002-12-13 20:15:29 +00002270bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002271 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002272{
2273 int ret;
2274
2275 ret = route_map_delete_set (index, command, arg);
2276 if (ret)
2277 {
2278 switch (ret)
2279 {
2280 case RMAP_RULE_MISSING:
2281 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2282 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002283 case RMAP_COMPILE_ERROR:
2284 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2285 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002286 }
2287 }
2288 return CMD_SUCCESS;
2289}
2290
2291/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002292static void
paulfd79ac92004-10-13 05:06:08 +00002293bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002294{
2295 int i;
2296 afi_t afi;
2297 safi_t safi;
2298 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002299 struct listnode *node, *nnode;
2300 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002301 struct bgp *bgp;
2302 struct peer *peer;
2303 struct peer_group *group;
2304 struct bgp_filter *filter;
2305 struct bgp_node *bn;
2306 struct bgp_static *bgp_static;
2307
2308 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002309 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002310 {
paul1eb8ef22005-04-07 07:30:20 +00002311 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002312 {
2313 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2314 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2315 {
2316 filter = &peer->filter[afi][safi];
2317
paulfee0f4c2004-09-13 05:12:46 +00002318 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002319 {
2320 if (filter->map[direct].name)
2321 filter->map[direct].map =
2322 route_map_lookup_by_name (filter->map[direct].name);
2323 else
2324 filter->map[direct].map = NULL;
2325 }
2326
2327 if (filter->usmap.name)
2328 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2329 else
2330 filter->usmap.map = NULL;
2331 }
2332 }
paul1eb8ef22005-04-07 07:30:20 +00002333 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002334 {
2335 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2336 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2337 {
2338 filter = &group->conf->filter[afi][safi];
2339
paulfee0f4c2004-09-13 05:12:46 +00002340 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002341 {
2342 if (filter->map[direct].name)
2343 filter->map[direct].map =
2344 route_map_lookup_by_name (filter->map[direct].name);
2345 else
2346 filter->map[direct].map = NULL;
2347 }
2348
2349 if (filter->usmap.name)
2350 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2351 else
2352 filter->usmap.map = NULL;
2353 }
2354 }
2355 }
2356
2357 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002358 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002359 {
paul1eb8ef22005-04-07 07:30:20 +00002360 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002361 {
2362 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2363 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2364 {
2365 if (peer->default_rmap[afi][safi].name)
2366 peer->default_rmap[afi][safi].map =
2367 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2368 else
2369 peer->default_rmap[afi][safi].map = NULL;
2370 }
2371 }
2372 }
2373
2374 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002375 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002376 {
2377 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2378 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2379 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2380 bn = bgp_route_next (bn))
2381 if ((bgp_static = bn->info) != NULL)
2382 {
2383 if (bgp_static->rmap.name)
2384 bgp_static->rmap.map =
2385 route_map_lookup_by_name (bgp_static->rmap.name);
2386 else
2387 bgp_static->rmap.map = NULL;
2388 }
2389 }
2390
2391 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002392 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002393 {
2394 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2395 {
2396 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2397 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2398 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2399#ifdef HAVE_IPV6
2400 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2401 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2402 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2403#endif /* HAVE_IPV6 */
2404 }
2405 }
2406}
2407
paulfee0f4c2004-09-13 05:12:46 +00002408DEFUN (match_peer,
2409 match_peer_cmd,
2410 "match peer (A.B.C.D|X:X::X:X)",
2411 MATCH_STR
2412 "Match peer address\n"
2413 "IPv6 address of peer\n"
2414 "IP address of peer\n")
2415{
2416 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2417}
2418
2419DEFUN (match_peer_local,
2420 match_peer_local_cmd,
2421 "match peer local",
2422 MATCH_STR
2423 "Match peer address\n"
2424 "Static or Redistributed routes\n")
2425{
2426 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2427}
2428
2429DEFUN (no_match_peer,
2430 no_match_peer_cmd,
2431 "no match peer",
2432 NO_STR
2433 MATCH_STR
2434 "Match peer address\n")
2435{
2436 if (argc == 0)
2437 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2438
2439 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2440}
2441
2442ALIAS (no_match_peer,
2443 no_match_peer_val_cmd,
2444 "no match peer (A.B.C.D|X:X::X:X)",
2445 NO_STR
2446 MATCH_STR
2447 "Match peer address\n"
2448 "IPv6 address of peer\n"
2449 "IP address of peer\n")
2450
2451ALIAS (no_match_peer,
2452 no_match_peer_local_cmd,
2453 "no match peer local",
2454 NO_STR
2455 MATCH_STR
2456 "Match peer address\n"
2457 "Static or Redistributed routes\n")
2458
paul718e3742002-12-13 20:15:29 +00002459DEFUN (match_ip_address,
2460 match_ip_address_cmd,
2461 "match ip address (<1-199>|<1300-2699>|WORD)",
2462 MATCH_STR
2463 IP_STR
2464 "Match address of route\n"
2465 "IP access-list number\n"
2466 "IP access-list number (expanded range)\n"
2467 "IP Access-list name\n")
2468{
2469 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2470}
2471
2472DEFUN (no_match_ip_address,
2473 no_match_ip_address_cmd,
2474 "no match ip address",
2475 NO_STR
2476 MATCH_STR
2477 IP_STR
2478 "Match address of route\n")
2479{
2480 if (argc == 0)
2481 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2482
2483 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2484}
2485
2486ALIAS (no_match_ip_address,
2487 no_match_ip_address_val_cmd,
2488 "no match ip address (<1-199>|<1300-2699>|WORD)",
2489 NO_STR
2490 MATCH_STR
2491 IP_STR
2492 "Match address of route\n"
2493 "IP access-list number\n"
2494 "IP access-list number (expanded range)\n"
2495 "IP Access-list name\n")
2496
2497DEFUN (match_ip_next_hop,
2498 match_ip_next_hop_cmd,
2499 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2500 MATCH_STR
2501 IP_STR
2502 "Match next-hop address of route\n"
2503 "IP access-list number\n"
2504 "IP access-list number (expanded range)\n"
2505 "IP Access-list name\n")
2506{
2507 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2508}
2509
2510DEFUN (no_match_ip_next_hop,
2511 no_match_ip_next_hop_cmd,
2512 "no match ip next-hop",
2513 NO_STR
2514 MATCH_STR
2515 IP_STR
2516 "Match next-hop address of route\n")
2517{
2518 if (argc == 0)
2519 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2520
2521 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2522}
2523
2524ALIAS (no_match_ip_next_hop,
2525 no_match_ip_next_hop_val_cmd,
2526 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2527 NO_STR
2528 MATCH_STR
2529 IP_STR
2530 "Match next-hop address of route\n"
2531 "IP access-list number\n"
2532 "IP access-list number (expanded range)\n"
2533 "IP Access-list name\n")
2534
hassoc1643bb2005-02-02 16:43:17 +00002535DEFUN (match_ip_route_source,
2536 match_ip_route_source_cmd,
2537 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2538 MATCH_STR
2539 IP_STR
2540 "Match advertising source address of route\n"
2541 "IP access-list number\n"
2542 "IP access-list number (expanded range)\n"
2543 "IP standard access-list name\n")
2544{
2545 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2546}
2547
2548DEFUN (no_match_ip_route_source,
2549 no_match_ip_route_source_cmd,
2550 "no match ip route-source",
2551 NO_STR
2552 MATCH_STR
2553 IP_STR
2554 "Match advertising source address of route\n")
2555{
2556 if (argc == 0)
2557 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2558
2559 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2560}
2561
2562ALIAS (no_match_ip_route_source,
2563 no_match_ip_route_source_val_cmd,
2564 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2565 NO_STR
2566 MATCH_STR
2567 IP_STR
2568 "Match advertising source address of route\n"
2569 "IP access-list number\n"
2570 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002571 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002572
paul718e3742002-12-13 20:15:29 +00002573DEFUN (match_ip_address_prefix_list,
2574 match_ip_address_prefix_list_cmd,
2575 "match ip address prefix-list WORD",
2576 MATCH_STR
2577 IP_STR
2578 "Match address of route\n"
2579 "Match entries of prefix-lists\n"
2580 "IP prefix-list name\n")
2581{
2582 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2583}
2584
2585DEFUN (no_match_ip_address_prefix_list,
2586 no_match_ip_address_prefix_list_cmd,
2587 "no match ip address prefix-list",
2588 NO_STR
2589 MATCH_STR
2590 IP_STR
2591 "Match address of route\n"
2592 "Match entries of prefix-lists\n")
2593{
2594 if (argc == 0)
2595 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2596
2597 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2598}
2599
2600ALIAS (no_match_ip_address_prefix_list,
2601 no_match_ip_address_prefix_list_val_cmd,
2602 "no match ip address prefix-list WORD",
2603 NO_STR
2604 MATCH_STR
2605 IP_STR
2606 "Match address of route\n"
2607 "Match entries of prefix-lists\n"
2608 "IP prefix-list name\n")
2609
2610DEFUN (match_ip_next_hop_prefix_list,
2611 match_ip_next_hop_prefix_list_cmd,
2612 "match ip next-hop prefix-list WORD",
2613 MATCH_STR
2614 IP_STR
2615 "Match next-hop address of route\n"
2616 "Match entries of prefix-lists\n"
2617 "IP prefix-list name\n")
2618{
2619 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2620}
2621
2622DEFUN (no_match_ip_next_hop_prefix_list,
2623 no_match_ip_next_hop_prefix_list_cmd,
2624 "no match ip next-hop prefix-list",
2625 NO_STR
2626 MATCH_STR
2627 IP_STR
2628 "Match next-hop address of route\n"
2629 "Match entries of prefix-lists\n")
2630{
2631 if (argc == 0)
2632 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2633
2634 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2635}
2636
2637ALIAS (no_match_ip_next_hop_prefix_list,
2638 no_match_ip_next_hop_prefix_list_val_cmd,
2639 "no match ip next-hop prefix-list WORD",
2640 NO_STR
2641 MATCH_STR
2642 IP_STR
2643 "Match next-hop address of route\n"
2644 "Match entries of prefix-lists\n"
2645 "IP prefix-list name\n")
2646
hassoc1643bb2005-02-02 16:43:17 +00002647DEFUN (match_ip_route_source_prefix_list,
2648 match_ip_route_source_prefix_list_cmd,
2649 "match ip route-source prefix-list WORD",
2650 MATCH_STR
2651 IP_STR
2652 "Match advertising source address of route\n"
2653 "Match entries of prefix-lists\n"
2654 "IP prefix-list name\n")
2655{
2656 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2657}
2658
2659DEFUN (no_match_ip_route_source_prefix_list,
2660 no_match_ip_route_source_prefix_list_cmd,
2661 "no match ip route-source prefix-list",
2662 NO_STR
2663 MATCH_STR
2664 IP_STR
2665 "Match advertising source address of route\n"
2666 "Match entries of prefix-lists\n")
2667{
2668 if (argc == 0)
2669 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2670
2671 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2672}
2673
2674ALIAS (no_match_ip_route_source_prefix_list,
2675 no_match_ip_route_source_prefix_list_val_cmd,
2676 "no match ip route-source prefix-list WORD",
2677 NO_STR
2678 MATCH_STR
2679 IP_STR
2680 "Match advertising source address of route\n"
2681 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002682 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002683
paul718e3742002-12-13 20:15:29 +00002684DEFUN (match_metric,
2685 match_metric_cmd,
2686 "match metric <0-4294967295>",
2687 MATCH_STR
2688 "Match metric of route\n"
2689 "Metric value\n")
2690{
2691 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2692}
2693
2694DEFUN (no_match_metric,
2695 no_match_metric_cmd,
2696 "no match metric",
2697 NO_STR
2698 MATCH_STR
2699 "Match metric of route\n")
2700{
2701 if (argc == 0)
2702 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2703
2704 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2705}
2706
2707ALIAS (no_match_metric,
2708 no_match_metric_val_cmd,
2709 "no match metric <0-4294967295>",
2710 NO_STR
2711 MATCH_STR
2712 "Match metric of route\n"
2713 "Metric value\n")
2714
2715DEFUN (match_community,
2716 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002717 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002718 MATCH_STR
2719 "Match BGP community list\n"
2720 "Community-list number (standard)\n"
2721 "Community-list number (expanded)\n"
2722 "Community-list name\n")
2723{
2724 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2725}
2726
2727DEFUN (match_community_exact,
2728 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002729 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002730 MATCH_STR
2731 "Match BGP community list\n"
2732 "Community-list number (standard)\n"
2733 "Community-list number (expanded)\n"
2734 "Community-list name\n"
2735 "Do exact matching of communities\n")
2736{
2737 int ret;
2738 char *argstr;
2739
2740 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2741 strlen (argv[0]) + strlen ("exact-match") + 2);
2742
2743 sprintf (argstr, "%s exact-match", argv[0]);
2744
2745 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2746
2747 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2748
2749 return ret;
2750}
2751
2752DEFUN (no_match_community,
2753 no_match_community_cmd,
2754 "no match community",
2755 NO_STR
2756 MATCH_STR
2757 "Match BGP community list\n")
2758{
2759 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2760}
2761
2762ALIAS (no_match_community,
2763 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002764 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002765 NO_STR
2766 MATCH_STR
2767 "Match BGP community list\n"
2768 "Community-list number (standard)\n"
2769 "Community-list number (expanded)\n"
2770 "Community-list name\n")
2771
2772ALIAS (no_match_community,
2773 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002774 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002775 NO_STR
2776 MATCH_STR
2777 "Match BGP community list\n"
2778 "Community-list number (standard)\n"
2779 "Community-list number (expanded)\n"
2780 "Community-list name\n"
2781 "Do exact matching of communities\n")
2782
paul73ffb252003-04-19 15:49:49 +00002783DEFUN (match_ecommunity,
2784 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002785 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002786 MATCH_STR
2787 "Match BGP/VPN extended community list\n"
2788 "Extended community-list number (standard)\n"
2789 "Extended community-list number (expanded)\n"
2790 "Extended community-list name\n")
2791{
2792 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2793}
2794
2795DEFUN (no_match_ecommunity,
2796 no_match_ecommunity_cmd,
2797 "no match extcommunity",
2798 NO_STR
2799 MATCH_STR
2800 "Match BGP/VPN extended community list\n")
2801{
2802 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2803}
2804
2805ALIAS (no_match_ecommunity,
2806 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002807 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002808 NO_STR
2809 MATCH_STR
2810 "Match BGP/VPN extended community list\n"
2811 "Extended community-list number (standard)\n"
2812 "Extended community-list number (expanded)\n"
2813 "Extended community-list name\n")
2814
paul718e3742002-12-13 20:15:29 +00002815DEFUN (match_aspath,
2816 match_aspath_cmd,
2817 "match as-path WORD",
2818 MATCH_STR
2819 "Match BGP AS path list\n"
2820 "AS path access-list name\n")
2821{
2822 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2823}
2824
2825DEFUN (no_match_aspath,
2826 no_match_aspath_cmd,
2827 "no match as-path",
2828 NO_STR
2829 MATCH_STR
2830 "Match BGP AS path list\n")
2831{
2832 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2833}
2834
2835ALIAS (no_match_aspath,
2836 no_match_aspath_val_cmd,
2837 "no match as-path WORD",
2838 NO_STR
2839 MATCH_STR
2840 "Match BGP AS path list\n"
2841 "AS path access-list name\n")
2842
2843DEFUN (match_origin,
2844 match_origin_cmd,
2845 "match origin (egp|igp|incomplete)",
2846 MATCH_STR
2847 "BGP origin code\n"
2848 "remote EGP\n"
2849 "local IGP\n"
2850 "unknown heritage\n")
2851{
2852 if (strncmp (argv[0], "igp", 2) == 0)
2853 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2854 if (strncmp (argv[0], "egp", 1) == 0)
2855 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2856 if (strncmp (argv[0], "incomplete", 2) == 0)
2857 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2858
2859 return CMD_WARNING;
2860}
2861
2862DEFUN (no_match_origin,
2863 no_match_origin_cmd,
2864 "no match origin",
2865 NO_STR
2866 MATCH_STR
2867 "BGP origin code\n")
2868{
2869 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2870}
2871
2872ALIAS (no_match_origin,
2873 no_match_origin_val_cmd,
2874 "no match origin (egp|igp|incomplete)",
2875 NO_STR
2876 MATCH_STR
2877 "BGP origin code\n"
2878 "remote EGP\n"
2879 "local IGP\n"
2880 "unknown heritage\n")
2881
2882DEFUN (set_ip_nexthop,
2883 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002884 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002885 SET_STR
2886 IP_STR
2887 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002888 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002889{
2890 union sockunion su;
2891 int ret;
2892
2893 ret = str2sockunion (argv[0], &su);
2894 if (ret < 0)
2895 {
2896 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2897 return CMD_WARNING;
2898 }
2899
2900 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2901}
2902
paulaf5cd0a2003-11-02 07:24:40 +00002903DEFUN (set_ip_nexthop_peer,
2904 set_ip_nexthop_peer_cmd,
2905 "set ip next-hop peer-address",
2906 SET_STR
2907 IP_STR
2908 "Next hop address\n"
2909 "Use peer address (for BGP only)\n")
2910{
2911 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2912}
2913
paul94f2b392005-06-28 12:44:16 +00002914DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002915 no_set_ip_nexthop_peer_cmd,
2916 "no set ip next-hop peer-address",
2917 NO_STR
2918 SET_STR
2919 IP_STR
2920 "Next hop address\n"
2921 "Use peer address (for BGP only)\n")
2922{
2923 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2924}
2925
2926
paul718e3742002-12-13 20:15:29 +00002927DEFUN (no_set_ip_nexthop,
2928 no_set_ip_nexthop_cmd,
2929 "no set ip next-hop",
2930 NO_STR
2931 SET_STR
paul718e3742002-12-13 20:15:29 +00002932 "Next hop address\n")
2933{
paulaf5cd0a2003-11-02 07:24:40 +00002934 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002935 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2936
2937 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2938}
2939
2940ALIAS (no_set_ip_nexthop,
2941 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002942 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002943 NO_STR
2944 SET_STR
2945 IP_STR
2946 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002947 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002948
2949DEFUN (set_metric,
2950 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002951 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002952 SET_STR
2953 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002954 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002955{
2956 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2957}
2958
paul73ffb252003-04-19 15:49:49 +00002959ALIAS (set_metric,
2960 set_metric_addsub_cmd,
2961 "set metric <+/-metric>",
2962 SET_STR
2963 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002964 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002965
paul718e3742002-12-13 20:15:29 +00002966DEFUN (no_set_metric,
2967 no_set_metric_cmd,
2968 "no set metric",
2969 NO_STR
2970 SET_STR
2971 "Metric value for destination routing protocol\n")
2972{
2973 if (argc == 0)
2974 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2975
2976 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2977}
2978
2979ALIAS (no_set_metric,
2980 no_set_metric_val_cmd,
2981 "no set metric <0-4294967295>",
2982 NO_STR
2983 SET_STR
2984 "Metric value for destination routing protocol\n"
2985 "Metric value\n")
2986
2987DEFUN (set_local_pref,
2988 set_local_pref_cmd,
2989 "set local-preference <0-4294967295>",
2990 SET_STR
2991 "BGP local preference path attribute\n"
2992 "Preference value\n")
2993{
2994 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2995}
2996
2997DEFUN (no_set_local_pref,
2998 no_set_local_pref_cmd,
2999 "no set local-preference",
3000 NO_STR
3001 SET_STR
3002 "BGP local preference path attribute\n")
3003{
3004 if (argc == 0)
3005 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3006
3007 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3008}
3009
3010ALIAS (no_set_local_pref,
3011 no_set_local_pref_val_cmd,
3012 "no set local-preference <0-4294967295>",
3013 NO_STR
3014 SET_STR
3015 "BGP local preference path attribute\n"
3016 "Preference value\n")
3017
3018DEFUN (set_weight,
3019 set_weight_cmd,
3020 "set weight <0-4294967295>",
3021 SET_STR
3022 "BGP weight for routing table\n"
3023 "Weight value\n")
3024{
3025 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3026}
3027
3028DEFUN (no_set_weight,
3029 no_set_weight_cmd,
3030 "no set weight",
3031 NO_STR
3032 SET_STR
3033 "BGP weight for routing table\n")
3034{
3035 if (argc == 0)
3036 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3037
3038 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3039}
3040
3041ALIAS (no_set_weight,
3042 no_set_weight_val_cmd,
3043 "no set weight <0-4294967295>",
3044 NO_STR
3045 SET_STR
3046 "BGP weight for routing table\n"
3047 "Weight value\n")
3048
3049DEFUN (set_aspath_prepend,
3050 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003051 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003052 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003053 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003054 "Prepend to the as-path\n"
3055 "AS number\n")
3056{
3057 int ret;
3058 char *str;
3059
3060 str = argv_concat (argv, argc, 0);
3061 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3062 XFREE (MTYPE_TMP, str);
3063
3064 return ret;
3065}
3066
3067DEFUN (no_set_aspath_prepend,
3068 no_set_aspath_prepend_cmd,
3069 "no set as-path prepend",
3070 NO_STR
3071 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003072 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003073 "Prepend to the as-path\n")
3074{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003075 int ret;
3076 char *str;
3077
3078 if (argc == 0)
3079 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3080
3081 str = argv_concat (argv, argc, 0);
3082 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3083 XFREE (MTYPE_TMP, str);
3084 return ret;
paul718e3742002-12-13 20:15:29 +00003085}
3086
3087ALIAS (no_set_aspath_prepend,
3088 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003089 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003090 NO_STR
3091 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003092 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003093 "Prepend to the as-path\n"
3094 "AS number\n")
3095
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003096DEFUN (set_aspath_exclude,
3097 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003098 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003099 SET_STR
3100 "Transform BGP AS-path attribute\n"
3101 "Exclude from the as-path\n"
3102 "AS number\n")
3103{
3104 int ret;
3105 char *str;
3106
3107 str = argv_concat (argv, argc, 0);
3108 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3109 XFREE (MTYPE_TMP, str);
3110 return ret;
3111}
3112
3113DEFUN (no_set_aspath_exclude,
3114 no_set_aspath_exclude_cmd,
3115 "no set as-path exclude",
3116 NO_STR
3117 SET_STR
3118 "Transform BGP AS_PATH attribute\n"
3119 "Exclude from the as-path\n")
3120{
3121 int ret;
3122 char *str;
3123
3124 if (argc == 0)
3125 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3126
3127 str = argv_concat (argv, argc, 0);
3128 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3129 XFREE (MTYPE_TMP, str);
3130 return ret;
3131}
3132
3133ALIAS (no_set_aspath_exclude,
3134 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003135 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003136 NO_STR
3137 SET_STR
3138 "Transform BGP AS_PATH attribute\n"
3139 "Exclude from the as-path\n"
3140 "AS number\n")
3141
paul718e3742002-12-13 20:15:29 +00003142DEFUN (set_community,
3143 set_community_cmd,
3144 "set community .AA:NN",
3145 SET_STR
3146 "BGP community attribute\n"
3147 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3148{
3149 int i;
3150 int first = 0;
3151 int additive = 0;
3152 struct buffer *b;
3153 struct community *com = NULL;
3154 char *str;
3155 char *argstr;
3156 int ret;
3157
3158 b = buffer_new (1024);
3159
3160 for (i = 0; i < argc; i++)
3161 {
3162 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3163 {
3164 additive = 1;
3165 continue;
3166 }
3167
3168 if (first)
3169 buffer_putc (b, ' ');
3170 else
3171 first = 1;
3172
3173 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3174 {
3175 buffer_putstr (b, "internet");
3176 continue;
3177 }
3178 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3179 {
3180 buffer_putstr (b, "local-AS");
3181 continue;
3182 }
3183 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3184 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3185 {
3186 buffer_putstr (b, "no-advertise");
3187 continue;
3188 }
3189 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3190 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3191 {
3192 buffer_putstr (b, "no-export");
3193 continue;
3194 }
3195 buffer_putstr (b, argv[i]);
3196 }
3197 buffer_putc (b, '\0');
3198
3199 /* Fetch result string then compile it to communities attribute. */
3200 str = buffer_getstr (b);
3201 buffer_free (b);
3202
3203 if (str)
3204 {
3205 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003206 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003207 }
3208
3209 /* Can't compile user input into communities attribute. */
3210 if (! com)
3211 {
3212 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3213 return CMD_WARNING;
3214 }
3215
3216 /* Set communites attribute string. */
3217 str = community_str (com);
3218
3219 if (additive)
3220 {
3221 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3222 strcpy (argstr, str);
3223 strcpy (argstr + strlen (str), " additive");
3224 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3225 XFREE (MTYPE_TMP, argstr);
3226 }
3227 else
3228 ret = bgp_route_set_add (vty, vty->index, "community", str);
3229
3230 community_free (com);
3231
3232 return ret;
3233}
3234
3235DEFUN (set_community_none,
3236 set_community_none_cmd,
3237 "set community none",
3238 SET_STR
3239 "BGP community attribute\n"
3240 "No community attribute\n")
3241{
3242 return bgp_route_set_add (vty, vty->index, "community", "none");
3243}
3244
3245DEFUN (no_set_community,
3246 no_set_community_cmd,
3247 "no set community",
3248 NO_STR
3249 SET_STR
3250 "BGP community attribute\n")
3251{
3252 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3253}
3254
3255ALIAS (no_set_community,
3256 no_set_community_val_cmd,
3257 "no set community .AA:NN",
3258 NO_STR
3259 SET_STR
3260 "BGP community attribute\n"
3261 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3262
3263ALIAS (no_set_community,
3264 no_set_community_none_cmd,
3265 "no set community none",
3266 NO_STR
3267 SET_STR
3268 "BGP community attribute\n"
3269 "No community attribute\n")
3270
3271DEFUN (set_community_delete,
3272 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003273 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003274 SET_STR
3275 "set BGP community list (for deletion)\n"
3276 "Community-list number (standard)\n"
3277 "Communitly-list number (expanded)\n"
3278 "Community-list name\n"
3279 "Delete matching communities\n")
3280{
3281 char *str;
3282
3283 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3284 strcpy (str, argv[0]);
3285 strcpy (str + strlen (argv[0]), " delete");
3286
3287 bgp_route_set_add (vty, vty->index, "comm-list", str);
3288
3289 XFREE (MTYPE_TMP, str);
3290 return CMD_SUCCESS;
3291}
3292
3293DEFUN (no_set_community_delete,
3294 no_set_community_delete_cmd,
3295 "no set comm-list",
3296 NO_STR
3297 SET_STR
3298 "set BGP community list (for deletion)\n")
3299{
3300 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3301}
3302
3303ALIAS (no_set_community_delete,
3304 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003305 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003306 NO_STR
3307 SET_STR
3308 "set BGP community list (for deletion)\n"
3309 "Community-list number (standard)\n"
3310 "Communitly-list number (expanded)\n"
3311 "Community-list name\n"
3312 "Delete matching communities\n")
3313
3314DEFUN (set_ecommunity_rt,
3315 set_ecommunity_rt_cmd,
3316 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3317 SET_STR
3318 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003319 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003320 "VPN extended community\n")
3321{
3322 int ret;
3323 char *str;
3324
3325 str = argv_concat (argv, argc, 0);
3326 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3327 XFREE (MTYPE_TMP, str);
3328
3329 return ret;
3330}
3331
3332DEFUN (no_set_ecommunity_rt,
3333 no_set_ecommunity_rt_cmd,
3334 "no set extcommunity rt",
3335 NO_STR
3336 SET_STR
3337 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003338 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003339{
3340 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3341}
3342
3343ALIAS (no_set_ecommunity_rt,
3344 no_set_ecommunity_rt_val_cmd,
3345 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3346 NO_STR
3347 SET_STR
3348 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003349 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003350 "VPN extended community\n")
3351
3352DEFUN (set_ecommunity_soo,
3353 set_ecommunity_soo_cmd,
3354 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3355 SET_STR
3356 "BGP extended community attribute\n"
3357 "Site-of-Origin extended community\n"
3358 "VPN extended community\n")
3359{
3360 int ret;
3361 char *str;
3362
3363 str = argv_concat (argv, argc, 0);
3364 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3365 XFREE (MTYPE_TMP, str);
3366 return ret;
3367}
3368
3369DEFUN (no_set_ecommunity_soo,
3370 no_set_ecommunity_soo_cmd,
3371 "no set extcommunity soo",
3372 NO_STR
3373 SET_STR
3374 "BGP extended community attribute\n"
3375 "Site-of-Origin extended community\n")
3376{
3377 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3378}
3379
3380ALIAS (no_set_ecommunity_soo,
3381 no_set_ecommunity_soo_val_cmd,
3382 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3383 NO_STR
3384 SET_STR
3385 "BGP extended community attribute\n"
3386 "Site-of-Origin extended community\n"
3387 "VPN extended community\n")
3388
3389DEFUN (set_origin,
3390 set_origin_cmd,
3391 "set origin (egp|igp|incomplete)",
3392 SET_STR
3393 "BGP origin code\n"
3394 "remote EGP\n"
3395 "local IGP\n"
3396 "unknown heritage\n")
3397{
3398 if (strncmp (argv[0], "igp", 2) == 0)
3399 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3400 if (strncmp (argv[0], "egp", 1) == 0)
3401 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3402 if (strncmp (argv[0], "incomplete", 2) == 0)
3403 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3404
3405 return CMD_WARNING;
3406}
3407
3408DEFUN (no_set_origin,
3409 no_set_origin_cmd,
3410 "no set origin",
3411 NO_STR
3412 SET_STR
3413 "BGP origin code\n")
3414{
3415 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3416}
3417
3418ALIAS (no_set_origin,
3419 no_set_origin_val_cmd,
3420 "no set origin (egp|igp|incomplete)",
3421 NO_STR
3422 SET_STR
3423 "BGP origin code\n"
3424 "remote EGP\n"
3425 "local IGP\n"
3426 "unknown heritage\n")
3427
3428DEFUN (set_atomic_aggregate,
3429 set_atomic_aggregate_cmd,
3430 "set atomic-aggregate",
3431 SET_STR
3432 "BGP atomic aggregate attribute\n" )
3433{
3434 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3435}
3436
3437DEFUN (no_set_atomic_aggregate,
3438 no_set_atomic_aggregate_cmd,
3439 "no set atomic-aggregate",
3440 NO_STR
3441 SET_STR
3442 "BGP atomic aggregate attribute\n" )
3443{
3444 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3445}
3446
3447DEFUN (set_aggregator_as,
3448 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003449 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003450 SET_STR
3451 "BGP aggregator attribute\n"
3452 "AS number of aggregator\n"
3453 "AS number\n"
3454 "IP address of aggregator\n")
3455{
3456 int ret;
3457 as_t as;
3458 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003459 char *argstr;
3460
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003461 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003462
paul718e3742002-12-13 20:15:29 +00003463 ret = inet_aton (argv[1], &address);
3464 if (ret == 0)
3465 {
3466 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3467 return CMD_WARNING;
3468 }
3469
3470 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3471 strlen (argv[0]) + strlen (argv[1]) + 2);
3472
3473 sprintf (argstr, "%s %s", argv[0], argv[1]);
3474
3475 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3476
3477 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3478
3479 return ret;
3480}
3481
3482DEFUN (no_set_aggregator_as,
3483 no_set_aggregator_as_cmd,
3484 "no set aggregator as",
3485 NO_STR
3486 SET_STR
3487 "BGP aggregator attribute\n"
3488 "AS number of aggregator\n")
3489{
3490 int ret;
3491 as_t as;
3492 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003493 char *argstr;
3494
3495 if (argv == 0)
3496 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3497
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003498 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003499
3500 ret = inet_aton (argv[1], &address);
3501 if (ret == 0)
3502 {
3503 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3504 return CMD_WARNING;
3505 }
3506
3507 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3508 strlen (argv[0]) + strlen (argv[1]) + 2);
3509
3510 sprintf (argstr, "%s %s", argv[0], argv[1]);
3511
3512 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3513
3514 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3515
3516 return ret;
3517}
3518
3519ALIAS (no_set_aggregator_as,
3520 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003521 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003522 NO_STR
3523 SET_STR
3524 "BGP aggregator attribute\n"
3525 "AS number of aggregator\n"
3526 "AS number\n"
3527 "IP address of aggregator\n")
3528
3529
3530#ifdef HAVE_IPV6
3531DEFUN (match_ipv6_address,
3532 match_ipv6_address_cmd,
3533 "match ipv6 address WORD",
3534 MATCH_STR
3535 IPV6_STR
3536 "Match IPv6 address of route\n"
3537 "IPv6 access-list name\n")
3538{
3539 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3540}
3541
3542DEFUN (no_match_ipv6_address,
3543 no_match_ipv6_address_cmd,
3544 "no match ipv6 address WORD",
3545 NO_STR
3546 MATCH_STR
3547 IPV6_STR
3548 "Match IPv6 address of route\n"
3549 "IPv6 access-list name\n")
3550{
3551 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3552}
3553
3554DEFUN (match_ipv6_next_hop,
3555 match_ipv6_next_hop_cmd,
3556 "match ipv6 next-hop X:X::X:X",
3557 MATCH_STR
3558 IPV6_STR
3559 "Match IPv6 next-hop address of route\n"
3560 "IPv6 address of next hop\n")
3561{
3562 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3563}
3564
3565DEFUN (no_match_ipv6_next_hop,
3566 no_match_ipv6_next_hop_cmd,
3567 "no match ipv6 next-hop X:X::X:X",
3568 NO_STR
3569 MATCH_STR
3570 IPV6_STR
3571 "Match IPv6 next-hop address of route\n"
3572 "IPv6 address of next hop\n")
3573{
3574 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3575}
3576
3577DEFUN (match_ipv6_address_prefix_list,
3578 match_ipv6_address_prefix_list_cmd,
3579 "match ipv6 address prefix-list WORD",
3580 MATCH_STR
3581 IPV6_STR
3582 "Match address of route\n"
3583 "Match entries of prefix-lists\n"
3584 "IP prefix-list name\n")
3585{
3586 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3587}
3588
3589DEFUN (no_match_ipv6_address_prefix_list,
3590 no_match_ipv6_address_prefix_list_cmd,
3591 "no match ipv6 address prefix-list WORD",
3592 NO_STR
3593 MATCH_STR
3594 IPV6_STR
3595 "Match address of route\n"
3596 "Match entries of prefix-lists\n"
3597 "IP prefix-list name\n")
3598{
3599 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3600}
3601
3602DEFUN (set_ipv6_nexthop_global,
3603 set_ipv6_nexthop_global_cmd,
3604 "set ipv6 next-hop global X:X::X:X",
3605 SET_STR
3606 IPV6_STR
3607 "IPv6 next-hop address\n"
3608 "IPv6 global address\n"
3609 "IPv6 address of next hop\n")
3610{
3611 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3612}
3613
3614DEFUN (no_set_ipv6_nexthop_global,
3615 no_set_ipv6_nexthop_global_cmd,
3616 "no set ipv6 next-hop global",
3617 NO_STR
3618 SET_STR
3619 IPV6_STR
3620 "IPv6 next-hop address\n"
3621 "IPv6 global address\n")
3622{
3623 if (argc == 0)
3624 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3625
3626 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3627}
3628
3629ALIAS (no_set_ipv6_nexthop_global,
3630 no_set_ipv6_nexthop_global_val_cmd,
3631 "no set ipv6 next-hop global X:X::X:X",
3632 NO_STR
3633 SET_STR
3634 IPV6_STR
3635 "IPv6 next-hop address\n"
3636 "IPv6 global address\n"
3637 "IPv6 address of next hop\n")
3638
3639DEFUN (set_ipv6_nexthop_local,
3640 set_ipv6_nexthop_local_cmd,
3641 "set ipv6 next-hop local X:X::X:X",
3642 SET_STR
3643 IPV6_STR
3644 "IPv6 next-hop address\n"
3645 "IPv6 local address\n"
3646 "IPv6 address of next hop\n")
3647{
3648 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3649}
3650
3651DEFUN (no_set_ipv6_nexthop_local,
3652 no_set_ipv6_nexthop_local_cmd,
3653 "no set ipv6 next-hop local",
3654 NO_STR
3655 SET_STR
3656 IPV6_STR
3657 "IPv6 next-hop address\n"
3658 "IPv6 local address\n")
3659{
3660 if (argc == 0)
3661 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3662
3663 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3664}
3665
3666ALIAS (no_set_ipv6_nexthop_local,
3667 no_set_ipv6_nexthop_local_val_cmd,
3668 "no set ipv6 next-hop local X:X::X:X",
3669 NO_STR
3670 SET_STR
3671 IPV6_STR
3672 "IPv6 next-hop address\n"
3673 "IPv6 local address\n"
3674 "IPv6 address of next hop\n")
3675#endif /* HAVE_IPV6 */
3676
3677DEFUN (set_vpnv4_nexthop,
3678 set_vpnv4_nexthop_cmd,
3679 "set vpnv4 next-hop A.B.C.D",
3680 SET_STR
3681 "VPNv4 information\n"
3682 "VPNv4 next-hop address\n"
3683 "IP address of next hop\n")
3684{
3685 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3686}
3687
3688DEFUN (no_set_vpnv4_nexthop,
3689 no_set_vpnv4_nexthop_cmd,
3690 "no set vpnv4 next-hop",
3691 NO_STR
3692 SET_STR
3693 "VPNv4 information\n"
3694 "VPNv4 next-hop address\n")
3695{
3696 if (argc == 0)
3697 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3698
3699 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3700}
3701
3702ALIAS (no_set_vpnv4_nexthop,
3703 no_set_vpnv4_nexthop_val_cmd,
3704 "no set vpnv4 next-hop A.B.C.D",
3705 NO_STR
3706 SET_STR
3707 "VPNv4 information\n"
3708 "VPNv4 next-hop address\n"
3709 "IP address of next hop\n")
3710
3711DEFUN (set_originator_id,
3712 set_originator_id_cmd,
3713 "set originator-id A.B.C.D",
3714 SET_STR
3715 "BGP originator ID attribute\n"
3716 "IP address of originator\n")
3717{
3718 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3719}
3720
3721DEFUN (no_set_originator_id,
3722 no_set_originator_id_cmd,
3723 "no set originator-id",
3724 NO_STR
3725 SET_STR
3726 "BGP originator ID attribute\n")
3727{
3728 if (argc == 0)
3729 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3730
3731 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3732}
3733
3734ALIAS (no_set_originator_id,
3735 no_set_originator_id_val_cmd,
3736 "no set originator-id A.B.C.D",
3737 NO_STR
3738 SET_STR
3739 "BGP originator ID attribute\n"
3740 "IP address of originator\n")
3741
Paul Jakma41367172007-08-06 15:24:51 +00003742DEFUN (set_pathlimit_ttl,
3743 set_pathlimit_ttl_cmd,
3744 "set pathlimit ttl <1-255>",
3745 SET_STR
3746 "BGP AS-Pathlimit attribute\n"
3747 "Set AS-Path Hop-count TTL\n")
3748{
3749 return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]);
3750}
3751
3752DEFUN (no_set_pathlimit_ttl,
3753 no_set_pathlimit_ttl_cmd,
3754 "no set pathlimit ttl",
3755 NO_STR
3756 SET_STR
3757 "BGP AS-Pathlimit attribute\n"
3758 "Set AS-Path Hop-count TTL\n")
3759{
3760 if (argc == 0)
3761 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL);
3762
3763 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]);
3764}
3765
3766ALIAS (no_set_pathlimit_ttl,
3767 no_set_pathlimit_ttl_val_cmd,
3768 "no set pathlimit ttl <1-255>",
3769 NO_STR
3770 MATCH_STR
3771 "BGP AS-Pathlimit attribute\n"
3772 "Set AS-Path Hop-count TTL\n")
3773
3774DEFUN (match_pathlimit_as,
3775 match_pathlimit_as_cmd,
3776 "match pathlimit as <1-65535>",
3777 MATCH_STR
3778 "BGP AS-Pathlimit attribute\n"
3779 "Match Pathlimit AS number\n")
3780{
3781 return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]);
3782}
3783
3784DEFUN (no_match_pathlimit_as,
3785 no_match_pathlimit_as_cmd,
3786 "no match pathlimit as",
3787 NO_STR
3788 MATCH_STR
3789 "BGP AS-Pathlimit attribute\n"
3790 "Match Pathlimit AS number\n")
3791{
3792 if (argc == 0)
3793 return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL);
3794
3795 return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]);
3796}
3797
3798ALIAS (no_match_pathlimit_as,
3799 no_match_pathlimit_as_val_cmd,
3800 "no match pathlimit as <1-65535>",
3801 NO_STR
3802 MATCH_STR
3803 "BGP AS-Pathlimit attribute\n"
3804 "Match Pathlimit ASN\n")
3805
paul718e3742002-12-13 20:15:29 +00003806
3807/* Initialization of route map. */
3808void
paul94f2b392005-06-28 12:44:16 +00003809bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003810{
3811 route_map_init ();
3812 route_map_init_vty ();
3813 route_map_add_hook (bgp_route_map_update);
3814 route_map_delete_hook (bgp_route_map_update);
3815
paulfee0f4c2004-09-13 05:12:46 +00003816 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003817 route_map_install_match (&route_match_ip_address_cmd);
3818 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003819 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003820 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3821 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003822 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003823 route_map_install_match (&route_match_aspath_cmd);
3824 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003825 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003826 route_map_install_match (&route_match_metric_cmd);
3827 route_map_install_match (&route_match_origin_cmd);
3828
3829 route_map_install_set (&route_set_ip_nexthop_cmd);
3830 route_map_install_set (&route_set_local_pref_cmd);
3831 route_map_install_set (&route_set_weight_cmd);
3832 route_map_install_set (&route_set_metric_cmd);
3833 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003834 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003835 route_map_install_set (&route_set_origin_cmd);
3836 route_map_install_set (&route_set_atomic_aggregate_cmd);
3837 route_map_install_set (&route_set_aggregator_as_cmd);
3838 route_map_install_set (&route_set_community_cmd);
3839 route_map_install_set (&route_set_community_delete_cmd);
3840 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3841 route_map_install_set (&route_set_originator_id_cmd);
3842 route_map_install_set (&route_set_ecommunity_rt_cmd);
3843 route_map_install_set (&route_set_ecommunity_soo_cmd);
3844
paulfee0f4c2004-09-13 05:12:46 +00003845 install_element (RMAP_NODE, &match_peer_cmd);
3846 install_element (RMAP_NODE, &match_peer_local_cmd);
3847 install_element (RMAP_NODE, &no_match_peer_cmd);
3848 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3849 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003850 install_element (RMAP_NODE, &match_ip_address_cmd);
3851 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3852 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3853 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3854 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3855 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003856 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3857 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3858 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003859
3860 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3861 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3862 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3863 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3864 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3865 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003866 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3867 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3868 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003869
3870 install_element (RMAP_NODE, &match_aspath_cmd);
3871 install_element (RMAP_NODE, &no_match_aspath_cmd);
3872 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3873 install_element (RMAP_NODE, &match_metric_cmd);
3874 install_element (RMAP_NODE, &no_match_metric_cmd);
3875 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3876 install_element (RMAP_NODE, &match_community_cmd);
3877 install_element (RMAP_NODE, &match_community_exact_cmd);
3878 install_element (RMAP_NODE, &no_match_community_cmd);
3879 install_element (RMAP_NODE, &no_match_community_val_cmd);
3880 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003881 install_element (RMAP_NODE, &match_ecommunity_cmd);
3882 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3883 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003884 install_element (RMAP_NODE, &match_origin_cmd);
3885 install_element (RMAP_NODE, &no_match_origin_cmd);
3886 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3887
3888 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003889 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003890 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3891 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3892 install_element (RMAP_NODE, &set_local_pref_cmd);
3893 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3894 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3895 install_element (RMAP_NODE, &set_weight_cmd);
3896 install_element (RMAP_NODE, &no_set_weight_cmd);
3897 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3898 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003899 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003900 install_element (RMAP_NODE, &no_set_metric_cmd);
3901 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3902 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003903 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003904 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3905 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003906 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3907 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003908 install_element (RMAP_NODE, &set_origin_cmd);
3909 install_element (RMAP_NODE, &no_set_origin_cmd);
3910 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3911 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3912 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3913 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3914 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3915 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3916 install_element (RMAP_NODE, &set_community_cmd);
3917 install_element (RMAP_NODE, &set_community_none_cmd);
3918 install_element (RMAP_NODE, &no_set_community_cmd);
3919 install_element (RMAP_NODE, &no_set_community_val_cmd);
3920 install_element (RMAP_NODE, &no_set_community_none_cmd);
3921 install_element (RMAP_NODE, &set_community_delete_cmd);
3922 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3923 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3924 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3925 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3926 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3927 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3928 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3929 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3930 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3931 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3932 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3933 install_element (RMAP_NODE, &set_originator_id_cmd);
3934 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3935 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3936
3937#ifdef HAVE_IPV6
3938 route_map_install_match (&route_match_ipv6_address_cmd);
3939 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3940 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3941 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3942 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003943
paul718e3742002-12-13 20:15:29 +00003944 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3945 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3946 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3947 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3948 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3949 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3950 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3951 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3952 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3953 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3954 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3955 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3956#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003957
3958 /* AS-Pathlimit */
3959 route_map_install_match (&route_match_pathlimit_as_cmd);
3960 route_map_install_set (&route_set_pathlimit_ttl_cmd);
3961
3962 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3963 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3964 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3965 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3966 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3967 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003968}