blob: 2d4a863006fa942c045e17de32c4704d0ba7e8e7 [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
paulac41b2a2003-08-12 05:32:27 +0000959 rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
960 memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
961
962 rins->address = address;
963 rins->peer_address = peer_address;
964
965 return rins;
paul718e3742002-12-13 20:15:29 +0000966}
967
968/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000969static void
paul718e3742002-12-13 20:15:29 +0000970route_set_ip_nexthop_free (void *rule)
971{
paulac41b2a2003-08-12 05:32:27 +0000972 struct rmap_ip_nexthop_set *rins = rule;
973
974 if (rins->address)
975 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
976
977 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000978}
979
980/* Route map commands for ip nexthop set. */
981struct route_map_rule_cmd route_set_ip_nexthop_cmd =
982{
983 "ip next-hop",
984 route_set_ip_nexthop,
985 route_set_ip_nexthop_compile,
986 route_set_ip_nexthop_free
987};
988
989/* `set local-preference LOCAL_PREF' */
990
991/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000992static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000993route_set_local_pref (void *rule, struct prefix *prefix,
994 route_map_object_t type, void *object)
995{
996 u_int32_t *local_pref;
997 struct bgp_info *bgp_info;
998
999 if (type == RMAP_BGP)
1000 {
1001 /* Fetch routemap's rule information. */
1002 local_pref = rule;
1003 bgp_info = object;
1004
1005 /* Set local preference value. */
1006 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1007 bgp_info->attr->local_pref = *local_pref;
1008 }
1009
1010 return RMAP_OKAY;
1011}
1012
1013/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001014static void *
paulfd79ac92004-10-13 05:06:08 +00001015route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001016{
paulfd79ac92004-10-13 05:06:08 +00001017 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001018 u_int32_t *local_pref;
1019 char *endptr = NULL;
1020
1021 /* Local preference value shoud be integer. */
1022 if (! all_digit (arg))
1023 return NULL;
paulfd79ac92004-10-13 05:06:08 +00001024
1025 tmp = strtoul (arg, &endptr, 10);
1026 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1027 return NULL;
1028
1029 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1030
1031 if (!local_pref)
1032 return local_pref;
1033
1034 *local_pref = tmp;
1035
paul718e3742002-12-13 20:15:29 +00001036 return local_pref;
1037}
1038
1039/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001040static void
paul718e3742002-12-13 20:15:29 +00001041route_set_local_pref_free (void *rule)
1042{
1043 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1044}
1045
1046/* Set local preference rule structure. */
1047struct route_map_rule_cmd route_set_local_pref_cmd =
1048{
1049 "local-preference",
1050 route_set_local_pref,
1051 route_set_local_pref_compile,
1052 route_set_local_pref_free,
1053};
1054
1055/* `set weight WEIGHT' */
1056
1057/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001058static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001059route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1060 void *object)
1061{
1062 u_int32_t *weight;
1063 struct bgp_info *bgp_info;
1064
1065 if (type == RMAP_BGP)
1066 {
1067 /* Fetch routemap's rule information. */
1068 weight = rule;
1069 bgp_info = object;
1070
1071 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001072 if (*weight)
1073 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1074 else if (bgp_info->attr->extra)
1075 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001076 }
1077
1078 return RMAP_OKAY;
1079}
1080
1081/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001082static void *
paulfd79ac92004-10-13 05:06:08 +00001083route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001084{
paulfd79ac92004-10-13 05:06:08 +00001085 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001086 u_int32_t *weight;
1087 char *endptr = NULL;
1088
1089 /* Local preference value shoud be integer. */
1090 if (! all_digit (arg))
1091 return NULL;
1092
paulfd79ac92004-10-13 05:06:08 +00001093
1094 tmp = strtoul (arg, &endptr, 10);
1095 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1096 return NULL;
1097
paul718e3742002-12-13 20:15:29 +00001098 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001099
1100 if (weight == NULL)
1101 return weight;
1102
1103 *weight = tmp;
1104
paul718e3742002-12-13 20:15:29 +00001105 return weight;
1106}
1107
1108/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001109static void
paul718e3742002-12-13 20:15:29 +00001110route_set_weight_free (void *rule)
1111{
1112 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1113}
1114
1115/* Set local preference rule structure. */
1116struct route_map_rule_cmd route_set_weight_cmd =
1117{
1118 "weight",
1119 route_set_weight,
1120 route_set_weight_compile,
1121 route_set_weight_free,
1122};
1123
1124/* `set metric METRIC' */
1125
1126/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001127static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001128route_set_metric (void *rule, struct prefix *prefix,
1129 route_map_object_t type, void *object)
1130{
1131 char *metric;
1132 u_int32_t metric_val;
1133 struct bgp_info *bgp_info;
1134
1135 if (type == RMAP_BGP)
1136 {
1137 /* Fetch routemap's rule information. */
1138 metric = rule;
1139 bgp_info = object;
1140
1141 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1142 bgp_info->attr->med = 0;
1143 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1144
1145 if (all_digit (metric))
1146 {
1147 metric_val = strtoul (metric, (char **)NULL, 10);
1148 bgp_info->attr->med = metric_val;
1149 }
1150 else
1151 {
1152 metric_val = strtoul (metric+1, (char **)NULL, 10);
1153
1154 if (strncmp (metric, "+", 1) == 0)
1155 {
paul3b424972003-10-13 09:47:32 +00001156 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1157 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001158 else
paul537d8ea2003-08-27 06:45:32 +00001159 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001160 }
1161 else if (strncmp (metric, "-", 1) == 0)
1162 {
paul537d8ea2003-08-27 06:45:32 +00001163 if (bgp_info->attr->med <= metric_val)
1164 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001165 else
paul537d8ea2003-08-27 06:45:32 +00001166 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001167 }
1168 }
1169 }
1170 return RMAP_OKAY;
1171}
1172
1173/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001174static void *
paulfd79ac92004-10-13 05:06:08 +00001175route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001176{
1177 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001178 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001179 char *endptr = NULL;
1180
1181 if (all_digit (arg))
1182 {
1183 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001184 larg = strtoul (arg, &endptr, 10);
1185 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001186 return NULL;
paul94f2b392005-06-28 12:44:16 +00001187 metric = larg;
paul718e3742002-12-13 20:15:29 +00001188 }
1189 else
1190 {
1191 /* set metric +/-value check */
1192 if ((strncmp (arg, "+", 1) != 0
1193 && strncmp (arg, "-", 1) != 0)
1194 || (! all_digit (arg+1)))
1195 return NULL;
1196
paul94f2b392005-06-28 12:44:16 +00001197 larg = strtoul (arg+1, &endptr, 10);
1198 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001199 return NULL;
paul94f2b392005-06-28 12:44:16 +00001200 metric = larg;
paul718e3742002-12-13 20:15:29 +00001201 }
1202
1203 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1204}
1205
1206/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001207static void
paul718e3742002-12-13 20:15:29 +00001208route_set_metric_free (void *rule)
1209{
1210 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1211}
1212
1213/* Set metric rule structure. */
1214struct route_map_rule_cmd route_set_metric_cmd =
1215{
1216 "metric",
1217 route_set_metric,
1218 route_set_metric_compile,
1219 route_set_metric_free,
1220};
1221
1222/* `set as-path prepend ASPATH' */
1223
1224/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001225static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001226route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1227{
1228 struct aspath *aspath;
1229 struct aspath *new;
1230 struct bgp_info *binfo;
1231
1232 if (type == RMAP_BGP)
1233 {
1234 aspath = rule;
1235 binfo = object;
1236
1237 if (binfo->attr->aspath->refcnt)
1238 new = aspath_dup (binfo->attr->aspath);
1239 else
1240 new = binfo->attr->aspath;
1241
1242 aspath_prepend (aspath, new);
1243 binfo->attr->aspath = new;
1244 }
1245
1246 return RMAP_OKAY;
1247}
1248
1249/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001250static void *
paulfd79ac92004-10-13 05:06:08 +00001251route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001252{
1253 struct aspath *aspath;
1254
1255 aspath = aspath_str2aspath (arg);
1256 if (! aspath)
1257 return NULL;
1258 return aspath;
1259}
1260
1261/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001262static void
paul718e3742002-12-13 20:15:29 +00001263route_set_aspath_prepend_free (void *rule)
1264{
1265 struct aspath *aspath = rule;
1266 aspath_free (aspath);
1267}
1268
1269/* Set metric rule structure. */
1270struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1271{
1272 "as-path prepend",
1273 route_set_aspath_prepend,
1274 route_set_aspath_prepend_compile,
1275 route_set_aspath_prepend_free,
1276};
1277
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001278/* `set as-path exclude ASn' */
1279
1280/* For ASN exclude mechanism.
1281 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1282 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1283 */
1284static route_map_result_t
1285route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1286{
1287 struct aspath * new_path, * exclude_path;
1288 struct bgp_info *binfo;
1289
1290 if (type == RMAP_BGP)
1291 {
1292 exclude_path = rule;
1293 binfo = object;
1294 if (binfo->attr->aspath->refcnt)
1295 new_path = aspath_dup (binfo->attr->aspath);
1296 else
1297 new_path = binfo->attr->aspath;
1298 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1299 }
1300 return RMAP_OKAY;
1301}
1302
1303/* FIXME: consider using route_set_aspath_prepend_compile() and
1304 * route_set_aspath_prepend_free(), which two below function are
1305 * exact clones of.
1306 */
1307
1308/* Compile function for as-path exclude. */
1309static void *
1310route_set_aspath_exclude_compile (const char *arg)
1311{
1312 struct aspath *aspath;
1313
1314 aspath = aspath_str2aspath (arg);
1315 if (! aspath)
1316 return NULL;
1317 return aspath;
1318}
1319
1320static void
1321route_set_aspath_exclude_free (void *rule)
1322{
1323 struct aspath *aspath = rule;
1324 aspath_free (aspath);
1325}
1326
1327/* Set ASn exlude rule structure. */
1328struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1329{
1330 "as-path exclude",
1331 route_set_aspath_exclude,
1332 route_set_aspath_exclude_compile,
1333 route_set_aspath_exclude_free,
1334};
1335
paul718e3742002-12-13 20:15:29 +00001336/* `set community COMMUNITY' */
1337struct rmap_com_set
1338{
1339 struct community *com;
1340 int additive;
1341 int none;
1342};
1343
1344/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001345static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001346route_set_community (void *rule, struct prefix *prefix,
1347 route_map_object_t type, void *object)
1348{
1349 struct rmap_com_set *rcs;
1350 struct bgp_info *binfo;
1351 struct attr *attr;
1352 struct community *new = NULL;
1353 struct community *old;
1354 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001355
paul718e3742002-12-13 20:15:29 +00001356 if (type == RMAP_BGP)
1357 {
1358 rcs = rule;
1359 binfo = object;
1360 attr = binfo->attr;
1361 old = attr->community;
1362
1363 /* "none" case. */
1364 if (rcs->none)
1365 {
1366 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1367 attr->community = NULL;
1368 return RMAP_OKAY;
1369 }
1370
1371 /* "additive" case. */
1372 if (rcs->additive && old)
1373 {
1374 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001375
1376 /* HACK: if the old community is not intern'd,
1377 * we should free it here, or all reference to it may be lost.
1378 * Really need to cleanup attribute caching sometime.
1379 */
1380 if (old->refcnt == 0)
1381 community_free (old);
paul718e3742002-12-13 20:15:29 +00001382 new = community_uniq_sort (merge);
1383 community_free (merge);
1384 }
1385 else
1386 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001387
1388 /* will be interned by caller if required */
paul718e3742002-12-13 20:15:29 +00001389 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001390
paul718e3742002-12-13 20:15:29 +00001391 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1392 }
1393
1394 return RMAP_OKAY;
1395}
1396
1397/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001398static void *
paulfd79ac92004-10-13 05:06:08 +00001399route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001400{
1401 struct rmap_com_set *rcs;
1402 struct community *com = NULL;
1403 char *sp;
1404 int additive = 0;
1405 int none = 0;
1406
1407 if (strcmp (arg, "none") == 0)
1408 none = 1;
1409 else
1410 {
1411 sp = strstr (arg, "additive");
1412
1413 if (sp && sp > arg)
1414 {
1415 /* "additive" keyworkd is included. */
1416 additive = 1;
1417 *(sp - 1) = '\0';
1418 }
1419
1420 com = community_str2com (arg);
1421
1422 if (additive)
1423 *(sp - 1) = ' ';
1424
1425 if (! com)
1426 return NULL;
1427 }
1428
1429 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1430 memset (rcs, 0, sizeof (struct rmap_com_set));
1431
1432 rcs->com = com;
1433 rcs->additive = additive;
1434 rcs->none = none;
1435
1436 return rcs;
1437}
1438
1439/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001440static void
paul718e3742002-12-13 20:15:29 +00001441route_set_community_free (void *rule)
1442{
1443 struct rmap_com_set *rcs = rule;
1444
1445 if (rcs->com)
1446 community_free (rcs->com);
1447 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1448}
1449
1450/* Set community rule structure. */
1451struct route_map_rule_cmd route_set_community_cmd =
1452{
1453 "community",
1454 route_set_community,
1455 route_set_community_compile,
1456 route_set_community_free,
1457};
1458
hassofee6e4e2005-02-02 16:29:31 +00001459/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001460
1461/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001462static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001463route_set_community_delete (void *rule, struct prefix *prefix,
1464 route_map_object_t type, void *object)
1465{
1466 struct community_list *list;
1467 struct community *merge;
1468 struct community *new;
1469 struct community *old;
1470 struct bgp_info *binfo;
1471
1472 if (type == RMAP_BGP)
1473 {
1474 if (! rule)
1475 return RMAP_OKAY;
1476
1477 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001478 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001479 old = binfo->attr->community;
1480
1481 if (list && old)
1482 {
1483 merge = community_list_match_delete (community_dup (old), list);
1484 new = community_uniq_sort (merge);
1485 community_free (merge);
1486
1487 if (new->size == 0)
1488 {
1489 binfo->attr->community = NULL;
1490 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1491 community_free (new);
1492 }
1493 else
1494 {
1495 binfo->attr->community = new;
1496 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1497 }
1498 }
1499 }
1500
1501 return RMAP_OKAY;
1502}
1503
1504/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001505static void *
paulfd79ac92004-10-13 05:06:08 +00001506route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001507{
1508 char *p;
1509 char *str;
1510 int len;
1511
1512 p = strchr (arg, ' ');
1513 if (p)
1514 {
1515 len = p - arg;
1516 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1517 memcpy (str, arg, len);
1518 }
1519 else
1520 str = NULL;
1521
1522 return str;
1523}
1524
1525/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001526static void
paul718e3742002-12-13 20:15:29 +00001527route_set_community_delete_free (void *rule)
1528{
1529 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1530}
1531
1532/* Set community rule structure. */
1533struct route_map_rule_cmd route_set_community_delete_cmd =
1534{
1535 "comm-list",
1536 route_set_community_delete,
1537 route_set_community_delete_compile,
1538 route_set_community_delete_free,
1539};
1540
1541/* `set extcommunity rt COMMUNITY' */
1542
1543/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001544static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001545route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1546 route_map_object_t type, void *object)
1547{
1548 struct ecommunity *ecom;
1549 struct ecommunity *new_ecom;
1550 struct ecommunity *old_ecom;
1551 struct bgp_info *bgp_info;
1552
1553 if (type == RMAP_BGP)
1554 {
1555 ecom = rule;
1556 bgp_info = object;
1557
1558 if (! ecom)
1559 return RMAP_OKAY;
1560
1561 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001562 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001563
1564 if (old_ecom)
1565 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1566 else
1567 new_ecom = ecommunity_dup (ecom);
1568
Paul Jakmafb982c22007-05-04 20:15:47 +00001569 bgp_info->attr->extra->ecommunity = new_ecom;
paul718e3742002-12-13 20:15:29 +00001570
hasso70601e02005-05-27 03:26:57 +00001571 if (old_ecom)
1572 ecommunity_free (old_ecom);
1573
paul718e3742002-12-13 20:15:29 +00001574 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1575 }
1576 return RMAP_OKAY;
1577}
1578
1579/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001580static void *
paulfd79ac92004-10-13 05:06:08 +00001581route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001582{
1583 struct ecommunity *ecom;
1584
1585 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1586 if (! ecom)
1587 return NULL;
1588 return ecom;
1589}
1590
1591/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001592static void
paul718e3742002-12-13 20:15:29 +00001593route_set_ecommunity_rt_free (void *rule)
1594{
1595 struct ecommunity *ecom = rule;
1596 ecommunity_free (ecom);
1597}
1598
1599/* Set community rule structure. */
1600struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1601{
1602 "extcommunity rt",
1603 route_set_ecommunity_rt,
1604 route_set_ecommunity_rt_compile,
1605 route_set_ecommunity_rt_free,
1606};
1607
1608/* `set extcommunity soo COMMUNITY' */
1609
1610/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001611static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001612route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1613 route_map_object_t type, void *object)
1614{
1615 struct ecommunity *ecom;
1616 struct bgp_info *bgp_info;
1617
1618 if (type == RMAP_BGP)
1619 {
1620 ecom = rule;
1621 bgp_info = object;
1622
1623 if (! ecom)
1624 return RMAP_OKAY;
1625
1626 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
Paul Jakmafb982c22007-05-04 20:15:47 +00001627 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
paul718e3742002-12-13 20:15:29 +00001628 }
1629 return RMAP_OKAY;
1630}
1631
1632/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001633static void *
paulfd79ac92004-10-13 05:06:08 +00001634route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001635{
1636 struct ecommunity *ecom;
1637
1638 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1639 if (! ecom)
1640 return NULL;
1641
1642 return ecom;
1643}
1644
1645/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001646static void
paul718e3742002-12-13 20:15:29 +00001647route_set_ecommunity_soo_free (void *rule)
1648{
1649 struct ecommunity *ecom = rule;
1650 ecommunity_free (ecom);
1651}
1652
1653/* Set community rule structure. */
1654struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1655{
1656 "extcommunity soo",
1657 route_set_ecommunity_soo,
1658 route_set_ecommunity_soo_compile,
1659 route_set_ecommunity_soo_free,
1660};
1661
1662/* `set origin ORIGIN' */
1663
1664/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001665static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001666route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1667{
1668 u_char *origin;
1669 struct bgp_info *bgp_info;
1670
1671 if (type == RMAP_BGP)
1672 {
1673 origin = rule;
1674 bgp_info = object;
1675
1676 bgp_info->attr->origin = *origin;
1677 }
1678
1679 return RMAP_OKAY;
1680}
1681
1682/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001683static void *
paulfd79ac92004-10-13 05:06:08 +00001684route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001685{
1686 u_char *origin;
1687
1688 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1689
1690 if (strcmp (arg, "igp") == 0)
1691 *origin = 0;
1692 else if (strcmp (arg, "egp") == 0)
1693 *origin = 1;
1694 else
1695 *origin = 2;
1696
1697 return origin;
1698}
1699
1700/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001701static void
paul718e3742002-12-13 20:15:29 +00001702route_set_origin_free (void *rule)
1703{
1704 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1705}
1706
1707/* Set metric rule structure. */
1708struct route_map_rule_cmd route_set_origin_cmd =
1709{
1710 "origin",
1711 route_set_origin,
1712 route_set_origin_compile,
1713 route_set_origin_free,
1714};
1715
1716/* `set atomic-aggregate' */
1717
1718/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001719static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001720route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1721 route_map_object_t type, void *object)
1722{
1723 struct bgp_info *bgp_info;
1724
1725 if (type == RMAP_BGP)
1726 {
1727 bgp_info = object;
1728 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1729 }
1730
1731 return RMAP_OKAY;
1732}
1733
1734/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001735static void *
paulfd79ac92004-10-13 05:06:08 +00001736route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001737{
1738 return (void *)1;
1739}
1740
1741/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001742static void
paul718e3742002-12-13 20:15:29 +00001743route_set_atomic_aggregate_free (void *rule)
1744{
1745 return;
1746}
1747
1748/* Set atomic aggregate rule structure. */
1749struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1750{
1751 "atomic-aggregate",
1752 route_set_atomic_aggregate,
1753 route_set_atomic_aggregate_compile,
1754 route_set_atomic_aggregate_free,
1755};
1756
1757/* `set aggregator as AS A.B.C.D' */
1758struct aggregator
1759{
1760 as_t as;
1761 struct in_addr address;
1762};
1763
paul94f2b392005-06-28 12:44:16 +00001764static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001765route_set_aggregator_as (void *rule, struct prefix *prefix,
1766 route_map_object_t type, void *object)
1767{
1768 struct bgp_info *bgp_info;
1769 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001770 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001771
1772 if (type == RMAP_BGP)
1773 {
1774 bgp_info = object;
1775 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001776 ae = bgp_attr_extra_get (bgp_info->attr);
1777
1778 ae->aggregator_as = aggregator->as;
1779 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001780 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1781 }
1782
1783 return RMAP_OKAY;
1784}
1785
paul94f2b392005-06-28 12:44:16 +00001786static void *
paulfd79ac92004-10-13 05:06:08 +00001787route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001788{
1789 struct aggregator *aggregator;
1790 char as[10];
1791 char address[20];
1792
1793 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1794 memset (aggregator, 0, sizeof (struct aggregator));
1795
1796 sscanf (arg, "%s %s", as, address);
1797
1798 aggregator->as = strtoul (as, NULL, 10);
1799 inet_aton (address, &aggregator->address);
1800
1801 return aggregator;
1802}
1803
paul94f2b392005-06-28 12:44:16 +00001804static void
paul718e3742002-12-13 20:15:29 +00001805route_set_aggregator_as_free (void *rule)
1806{
1807 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1808}
1809
1810struct route_map_rule_cmd route_set_aggregator_as_cmd =
1811{
1812 "aggregator as",
1813 route_set_aggregator_as,
1814 route_set_aggregator_as_compile,
1815 route_set_aggregator_as_free,
1816};
1817
1818#ifdef HAVE_IPV6
1819/* `match ipv6 address IP_ACCESS_LIST' */
1820
paul94f2b392005-06-28 12:44:16 +00001821static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001822route_match_ipv6_address (void *rule, struct prefix *prefix,
1823 route_map_object_t type, void *object)
1824{
1825 struct access_list *alist;
1826
1827 if (type == RMAP_BGP)
1828 {
1829 alist = access_list_lookup (AFI_IP6, (char *) rule);
1830 if (alist == NULL)
1831 return RMAP_NOMATCH;
1832
1833 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1834 RMAP_NOMATCH : RMAP_MATCH);
1835 }
1836 return RMAP_NOMATCH;
1837}
1838
paul94f2b392005-06-28 12:44:16 +00001839static void *
paulfd79ac92004-10-13 05:06:08 +00001840route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001841{
1842 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1843}
1844
paul94f2b392005-06-28 12:44:16 +00001845static void
paul718e3742002-12-13 20:15:29 +00001846route_match_ipv6_address_free (void *rule)
1847{
1848 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1849}
1850
1851/* Route map commands for ip address matching. */
1852struct route_map_rule_cmd route_match_ipv6_address_cmd =
1853{
1854 "ipv6 address",
1855 route_match_ipv6_address,
1856 route_match_ipv6_address_compile,
1857 route_match_ipv6_address_free
1858};
1859
1860/* `match ipv6 next-hop IP_ADDRESS' */
1861
paul94f2b392005-06-28 12:44:16 +00001862static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001863route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1864 route_map_object_t type, void *object)
1865{
1866 struct in6_addr *addr;
1867 struct bgp_info *bgp_info;
1868
1869 if (type == RMAP_BGP)
1870 {
1871 addr = rule;
1872 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001873
1874 if (!bgp_info->attr->extra)
1875 return RMAP_NOMATCH;
1876
1877 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001878 return RMAP_MATCH;
1879
Paul Jakmafb982c22007-05-04 20:15:47 +00001880 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1881 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001882 return RMAP_MATCH;
1883
1884 return RMAP_NOMATCH;
1885 }
1886
1887 return RMAP_NOMATCH;
1888}
1889
paul94f2b392005-06-28 12:44:16 +00001890static void *
paulfd79ac92004-10-13 05:06:08 +00001891route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001892{
1893 struct in6_addr *address;
1894 int ret;
1895
1896 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1897
1898 ret = inet_pton (AF_INET6, arg, address);
1899 if (!ret)
1900 {
1901 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1902 return NULL;
1903 }
1904
1905 return address;
1906}
1907
paul94f2b392005-06-28 12:44:16 +00001908static void
paul718e3742002-12-13 20:15:29 +00001909route_match_ipv6_next_hop_free (void *rule)
1910{
1911 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1912}
1913
1914struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1915{
1916 "ipv6 next-hop",
1917 route_match_ipv6_next_hop,
1918 route_match_ipv6_next_hop_compile,
1919 route_match_ipv6_next_hop_free
1920};
1921
1922/* `match ipv6 address prefix-list PREFIX_LIST' */
1923
paul94f2b392005-06-28 12:44:16 +00001924static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001925route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1926 route_map_object_t type, void *object)
1927{
1928 struct prefix_list *plist;
1929
1930 if (type == RMAP_BGP)
1931 {
1932 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1933 if (plist == NULL)
1934 return RMAP_NOMATCH;
1935
1936 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1937 RMAP_NOMATCH : RMAP_MATCH);
1938 }
1939 return RMAP_NOMATCH;
1940}
1941
paul94f2b392005-06-28 12:44:16 +00001942static void *
paulfd79ac92004-10-13 05:06:08 +00001943route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001944{
1945 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1946}
1947
paul94f2b392005-06-28 12:44:16 +00001948static void
paul718e3742002-12-13 20:15:29 +00001949route_match_ipv6_address_prefix_list_free (void *rule)
1950{
1951 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1952}
1953
1954struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1955{
1956 "ipv6 address prefix-list",
1957 route_match_ipv6_address_prefix_list,
1958 route_match_ipv6_address_prefix_list_compile,
1959 route_match_ipv6_address_prefix_list_free
1960};
1961
1962/* `set ipv6 nexthop global IP_ADDRESS' */
1963
1964/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001965static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001966route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1967 route_map_object_t type, void *object)
1968{
1969 struct in6_addr *address;
1970 struct bgp_info *bgp_info;
1971
1972 if (type == RMAP_BGP)
1973 {
1974 /* Fetch routemap's rule information. */
1975 address = rule;
1976 bgp_info = object;
1977
1978 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001979 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001980
1981 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001982 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1983 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001984 }
1985
1986 return RMAP_OKAY;
1987}
1988
1989/* Route map `ip next-hop' compile function. Given string is converted
1990 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001991static void *
paulfd79ac92004-10-13 05:06:08 +00001992route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001993{
1994 int ret;
1995 struct in6_addr *address;
1996
1997 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1998
1999 ret = inet_pton (AF_INET6, arg, address);
2000
2001 if (ret == 0)
2002 {
2003 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2004 return NULL;
2005 }
2006
2007 return address;
2008}
2009
2010/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002011static void
paul718e3742002-12-13 20:15:29 +00002012route_set_ipv6_nexthop_global_free (void *rule)
2013{
2014 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2015}
2016
2017/* Route map commands for ip nexthop set. */
2018struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2019{
2020 "ipv6 next-hop global",
2021 route_set_ipv6_nexthop_global,
2022 route_set_ipv6_nexthop_global_compile,
2023 route_set_ipv6_nexthop_global_free
2024};
2025
2026/* `set ipv6 nexthop local IP_ADDRESS' */
2027
2028/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002029static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002030route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2031 route_map_object_t type, void *object)
2032{
2033 struct in6_addr *address;
2034 struct bgp_info *bgp_info;
2035
2036 if (type == RMAP_BGP)
2037 {
2038 /* Fetch routemap's rule information. */
2039 address = rule;
2040 bgp_info = object;
2041
2042 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002043 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002044
2045 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002046 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2047 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002048 }
2049
2050 return RMAP_OKAY;
2051}
2052
2053/* Route map `ip nexthop' compile function. Given string is converted
2054 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002055static void *
paulfd79ac92004-10-13 05:06:08 +00002056route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002057{
2058 int ret;
2059 struct in6_addr *address;
2060
2061 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2062
2063 ret = inet_pton (AF_INET6, arg, address);
2064
2065 if (ret == 0)
2066 {
2067 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2068 return NULL;
2069 }
2070
2071 return address;
2072}
2073
2074/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002075static void
paul718e3742002-12-13 20:15:29 +00002076route_set_ipv6_nexthop_local_free (void *rule)
2077{
2078 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2079}
2080
2081/* Route map commands for ip nexthop set. */
2082struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2083{
2084 "ipv6 next-hop local",
2085 route_set_ipv6_nexthop_local,
2086 route_set_ipv6_nexthop_local_compile,
2087 route_set_ipv6_nexthop_local_free
2088};
2089#endif /* HAVE_IPV6 */
2090
2091/* `set vpnv4 nexthop A.B.C.D' */
2092
paul94f2b392005-06-28 12:44:16 +00002093static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002094route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2095 route_map_object_t type, void *object)
2096{
2097 struct in_addr *address;
2098 struct bgp_info *bgp_info;
2099
2100 if (type == RMAP_BGP)
2101 {
2102 /* Fetch routemap's rule information. */
2103 address = rule;
2104 bgp_info = object;
2105
2106 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002107 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002108 }
2109
2110 return RMAP_OKAY;
2111}
2112
paul94f2b392005-06-28 12:44:16 +00002113static void *
paulfd79ac92004-10-13 05:06:08 +00002114route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002115{
2116 int ret;
2117 struct in_addr *address;
2118
2119 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2120
2121 ret = inet_aton (arg, address);
2122
2123 if (ret == 0)
2124 {
2125 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2126 return NULL;
2127 }
2128
2129 return address;
2130}
2131
paul94f2b392005-06-28 12:44:16 +00002132static void
paul718e3742002-12-13 20:15:29 +00002133route_set_vpnv4_nexthop_free (void *rule)
2134{
2135 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2136}
2137
2138/* Route map commands for ip nexthop set. */
2139struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2140{
2141 "vpnv4 next-hop",
2142 route_set_vpnv4_nexthop,
2143 route_set_vpnv4_nexthop_compile,
2144 route_set_vpnv4_nexthop_free
2145};
2146
2147/* `set originator-id' */
2148
2149/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002150static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002151route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2152{
2153 struct in_addr *address;
2154 struct bgp_info *bgp_info;
2155
2156 if (type == RMAP_BGP)
2157 {
2158 address = rule;
2159 bgp_info = object;
2160
2161 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002162 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002163 }
2164
2165 return RMAP_OKAY;
2166}
2167
2168/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002169static void *
paulfd79ac92004-10-13 05:06:08 +00002170route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002171{
2172 int ret;
2173 struct in_addr *address;
2174
2175 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2176
2177 ret = inet_aton (arg, address);
2178
2179 if (ret == 0)
2180 {
2181 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2182 return NULL;
2183 }
2184
2185 return address;
2186}
2187
2188/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002189static void
paul718e3742002-12-13 20:15:29 +00002190route_set_originator_id_free (void *rule)
2191{
2192 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2193}
2194
2195/* Set metric rule structure. */
2196struct route_map_rule_cmd route_set_originator_id_cmd =
2197{
2198 "originator-id",
2199 route_set_originator_id,
2200 route_set_originator_id_compile,
2201 route_set_originator_id_free,
2202};
2203
2204/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002205static int
paul718e3742002-12-13 20:15:29 +00002206bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002207 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002208{
2209 int ret;
2210
2211 ret = route_map_add_match (index, command, arg);
2212 if (ret)
2213 {
2214 switch (ret)
2215 {
2216 case RMAP_RULE_MISSING:
2217 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2218 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002219 case RMAP_COMPILE_ERROR:
2220 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2221 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002222 }
2223 }
2224 return CMD_SUCCESS;
2225}
2226
2227/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002228static int
paul718e3742002-12-13 20:15:29 +00002229bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002230 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002231{
2232 int ret;
2233
2234 ret = route_map_delete_match (index, command, arg);
2235 if (ret)
2236 {
2237 switch (ret)
2238 {
2239 case RMAP_RULE_MISSING:
2240 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2241 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002242 case RMAP_COMPILE_ERROR:
2243 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2244 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002245 }
2246 }
2247 return CMD_SUCCESS;
2248}
2249
2250/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002251static int
paul718e3742002-12-13 20:15:29 +00002252bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002253 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002254{
2255 int ret;
2256
2257 ret = route_map_add_set (index, command, arg);
2258 if (ret)
2259 {
2260 switch (ret)
2261 {
2262 case RMAP_RULE_MISSING:
2263 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2264 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002265 case RMAP_COMPILE_ERROR:
2266 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2267 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002268 }
2269 }
2270 return CMD_SUCCESS;
2271}
2272
2273/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002274static int
paul718e3742002-12-13 20:15:29 +00002275bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002276 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002277{
2278 int ret;
2279
2280 ret = route_map_delete_set (index, command, arg);
2281 if (ret)
2282 {
2283 switch (ret)
2284 {
2285 case RMAP_RULE_MISSING:
2286 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2287 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002288 case RMAP_COMPILE_ERROR:
2289 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2290 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002291 }
2292 }
2293 return CMD_SUCCESS;
2294}
2295
2296/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002297static void
paulfd79ac92004-10-13 05:06:08 +00002298bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002299{
2300 int i;
2301 afi_t afi;
2302 safi_t safi;
2303 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002304 struct listnode *node, *nnode;
2305 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002306 struct bgp *bgp;
2307 struct peer *peer;
2308 struct peer_group *group;
2309 struct bgp_filter *filter;
2310 struct bgp_node *bn;
2311 struct bgp_static *bgp_static;
2312
2313 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002314 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002315 {
paul1eb8ef22005-04-07 07:30:20 +00002316 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002317 {
2318 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2319 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2320 {
2321 filter = &peer->filter[afi][safi];
2322
paulfee0f4c2004-09-13 05:12:46 +00002323 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002324 {
2325 if (filter->map[direct].name)
2326 filter->map[direct].map =
2327 route_map_lookup_by_name (filter->map[direct].name);
2328 else
2329 filter->map[direct].map = NULL;
2330 }
2331
2332 if (filter->usmap.name)
2333 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2334 else
2335 filter->usmap.map = NULL;
2336 }
2337 }
paul1eb8ef22005-04-07 07:30:20 +00002338 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002339 {
2340 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2341 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2342 {
2343 filter = &group->conf->filter[afi][safi];
2344
paulfee0f4c2004-09-13 05:12:46 +00002345 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002346 {
2347 if (filter->map[direct].name)
2348 filter->map[direct].map =
2349 route_map_lookup_by_name (filter->map[direct].name);
2350 else
2351 filter->map[direct].map = NULL;
2352 }
2353
2354 if (filter->usmap.name)
2355 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2356 else
2357 filter->usmap.map = NULL;
2358 }
2359 }
2360 }
2361
2362 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002363 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002364 {
paul1eb8ef22005-04-07 07:30:20 +00002365 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002366 {
2367 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2368 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2369 {
2370 if (peer->default_rmap[afi][safi].name)
2371 peer->default_rmap[afi][safi].map =
2372 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2373 else
2374 peer->default_rmap[afi][safi].map = NULL;
2375 }
2376 }
2377 }
2378
2379 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002380 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002381 {
2382 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2383 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2384 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2385 bn = bgp_route_next (bn))
2386 if ((bgp_static = bn->info) != NULL)
2387 {
2388 if (bgp_static->rmap.name)
2389 bgp_static->rmap.map =
2390 route_map_lookup_by_name (bgp_static->rmap.name);
2391 else
2392 bgp_static->rmap.map = NULL;
2393 }
2394 }
2395
2396 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002397 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002398 {
2399 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2400 {
2401 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2402 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2403 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2404#ifdef HAVE_IPV6
2405 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2406 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2407 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2408#endif /* HAVE_IPV6 */
2409 }
2410 }
2411}
2412
paulfee0f4c2004-09-13 05:12:46 +00002413DEFUN (match_peer,
2414 match_peer_cmd,
2415 "match peer (A.B.C.D|X:X::X:X)",
2416 MATCH_STR
2417 "Match peer address\n"
2418 "IPv6 address of peer\n"
2419 "IP address of peer\n")
2420{
2421 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2422}
2423
2424DEFUN (match_peer_local,
2425 match_peer_local_cmd,
2426 "match peer local",
2427 MATCH_STR
2428 "Match peer address\n"
2429 "Static or Redistributed routes\n")
2430{
2431 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2432}
2433
2434DEFUN (no_match_peer,
2435 no_match_peer_cmd,
2436 "no match peer",
2437 NO_STR
2438 MATCH_STR
2439 "Match peer address\n")
2440{
2441 if (argc == 0)
2442 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2443
2444 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2445}
2446
2447ALIAS (no_match_peer,
2448 no_match_peer_val_cmd,
2449 "no match peer (A.B.C.D|X:X::X:X)",
2450 NO_STR
2451 MATCH_STR
2452 "Match peer address\n"
2453 "IPv6 address of peer\n"
2454 "IP address of peer\n")
2455
2456ALIAS (no_match_peer,
2457 no_match_peer_local_cmd,
2458 "no match peer local",
2459 NO_STR
2460 MATCH_STR
2461 "Match peer address\n"
2462 "Static or Redistributed routes\n")
2463
paul718e3742002-12-13 20:15:29 +00002464DEFUN (match_ip_address,
2465 match_ip_address_cmd,
2466 "match ip address (<1-199>|<1300-2699>|WORD)",
2467 MATCH_STR
2468 IP_STR
2469 "Match address of route\n"
2470 "IP access-list number\n"
2471 "IP access-list number (expanded range)\n"
2472 "IP Access-list name\n")
2473{
2474 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2475}
2476
2477DEFUN (no_match_ip_address,
2478 no_match_ip_address_cmd,
2479 "no match ip address",
2480 NO_STR
2481 MATCH_STR
2482 IP_STR
2483 "Match address of route\n")
2484{
2485 if (argc == 0)
2486 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2487
2488 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2489}
2490
2491ALIAS (no_match_ip_address,
2492 no_match_ip_address_val_cmd,
2493 "no match ip address (<1-199>|<1300-2699>|WORD)",
2494 NO_STR
2495 MATCH_STR
2496 IP_STR
2497 "Match address of route\n"
2498 "IP access-list number\n"
2499 "IP access-list number (expanded range)\n"
2500 "IP Access-list name\n")
2501
2502DEFUN (match_ip_next_hop,
2503 match_ip_next_hop_cmd,
2504 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2505 MATCH_STR
2506 IP_STR
2507 "Match next-hop address of route\n"
2508 "IP access-list number\n"
2509 "IP access-list number (expanded range)\n"
2510 "IP Access-list name\n")
2511{
2512 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2513}
2514
2515DEFUN (no_match_ip_next_hop,
2516 no_match_ip_next_hop_cmd,
2517 "no match ip next-hop",
2518 NO_STR
2519 MATCH_STR
2520 IP_STR
2521 "Match next-hop address of route\n")
2522{
2523 if (argc == 0)
2524 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2525
2526 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2527}
2528
2529ALIAS (no_match_ip_next_hop,
2530 no_match_ip_next_hop_val_cmd,
2531 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2532 NO_STR
2533 MATCH_STR
2534 IP_STR
2535 "Match next-hop address of route\n"
2536 "IP access-list number\n"
2537 "IP access-list number (expanded range)\n"
2538 "IP Access-list name\n")
2539
hassoc1643bb2005-02-02 16:43:17 +00002540DEFUN (match_ip_route_source,
2541 match_ip_route_source_cmd,
2542 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2543 MATCH_STR
2544 IP_STR
2545 "Match advertising source address of route\n"
2546 "IP access-list number\n"
2547 "IP access-list number (expanded range)\n"
2548 "IP standard access-list name\n")
2549{
2550 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2551}
2552
2553DEFUN (no_match_ip_route_source,
2554 no_match_ip_route_source_cmd,
2555 "no match ip route-source",
2556 NO_STR
2557 MATCH_STR
2558 IP_STR
2559 "Match advertising source address of route\n")
2560{
2561 if (argc == 0)
2562 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2563
2564 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2565}
2566
2567ALIAS (no_match_ip_route_source,
2568 no_match_ip_route_source_val_cmd,
2569 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2570 NO_STR
2571 MATCH_STR
2572 IP_STR
2573 "Match advertising source address of route\n"
2574 "IP access-list number\n"
2575 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002576 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002577
paul718e3742002-12-13 20:15:29 +00002578DEFUN (match_ip_address_prefix_list,
2579 match_ip_address_prefix_list_cmd,
2580 "match ip address prefix-list WORD",
2581 MATCH_STR
2582 IP_STR
2583 "Match address of route\n"
2584 "Match entries of prefix-lists\n"
2585 "IP prefix-list name\n")
2586{
2587 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2588}
2589
2590DEFUN (no_match_ip_address_prefix_list,
2591 no_match_ip_address_prefix_list_cmd,
2592 "no match ip address prefix-list",
2593 NO_STR
2594 MATCH_STR
2595 IP_STR
2596 "Match address of route\n"
2597 "Match entries of prefix-lists\n")
2598{
2599 if (argc == 0)
2600 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2601
2602 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2603}
2604
2605ALIAS (no_match_ip_address_prefix_list,
2606 no_match_ip_address_prefix_list_val_cmd,
2607 "no match ip address prefix-list WORD",
2608 NO_STR
2609 MATCH_STR
2610 IP_STR
2611 "Match address of route\n"
2612 "Match entries of prefix-lists\n"
2613 "IP prefix-list name\n")
2614
2615DEFUN (match_ip_next_hop_prefix_list,
2616 match_ip_next_hop_prefix_list_cmd,
2617 "match ip next-hop prefix-list WORD",
2618 MATCH_STR
2619 IP_STR
2620 "Match next-hop address of route\n"
2621 "Match entries of prefix-lists\n"
2622 "IP prefix-list name\n")
2623{
2624 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2625}
2626
2627DEFUN (no_match_ip_next_hop_prefix_list,
2628 no_match_ip_next_hop_prefix_list_cmd,
2629 "no match ip next-hop prefix-list",
2630 NO_STR
2631 MATCH_STR
2632 IP_STR
2633 "Match next-hop address of route\n"
2634 "Match entries of prefix-lists\n")
2635{
2636 if (argc == 0)
2637 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2638
2639 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2640}
2641
2642ALIAS (no_match_ip_next_hop_prefix_list,
2643 no_match_ip_next_hop_prefix_list_val_cmd,
2644 "no match ip next-hop prefix-list WORD",
2645 NO_STR
2646 MATCH_STR
2647 IP_STR
2648 "Match next-hop address of route\n"
2649 "Match entries of prefix-lists\n"
2650 "IP prefix-list name\n")
2651
hassoc1643bb2005-02-02 16:43:17 +00002652DEFUN (match_ip_route_source_prefix_list,
2653 match_ip_route_source_prefix_list_cmd,
2654 "match ip route-source prefix-list WORD",
2655 MATCH_STR
2656 IP_STR
2657 "Match advertising source address of route\n"
2658 "Match entries of prefix-lists\n"
2659 "IP prefix-list name\n")
2660{
2661 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2662}
2663
2664DEFUN (no_match_ip_route_source_prefix_list,
2665 no_match_ip_route_source_prefix_list_cmd,
2666 "no match ip route-source prefix-list",
2667 NO_STR
2668 MATCH_STR
2669 IP_STR
2670 "Match advertising source address of route\n"
2671 "Match entries of prefix-lists\n")
2672{
2673 if (argc == 0)
2674 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2675
2676 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2677}
2678
2679ALIAS (no_match_ip_route_source_prefix_list,
2680 no_match_ip_route_source_prefix_list_val_cmd,
2681 "no match ip route-source prefix-list WORD",
2682 NO_STR
2683 MATCH_STR
2684 IP_STR
2685 "Match advertising source address of route\n"
2686 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002687 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002688
paul718e3742002-12-13 20:15:29 +00002689DEFUN (match_metric,
2690 match_metric_cmd,
2691 "match metric <0-4294967295>",
2692 MATCH_STR
2693 "Match metric of route\n"
2694 "Metric value\n")
2695{
2696 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2697}
2698
2699DEFUN (no_match_metric,
2700 no_match_metric_cmd,
2701 "no match metric",
2702 NO_STR
2703 MATCH_STR
2704 "Match metric of route\n")
2705{
2706 if (argc == 0)
2707 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2708
2709 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2710}
2711
2712ALIAS (no_match_metric,
2713 no_match_metric_val_cmd,
2714 "no match metric <0-4294967295>",
2715 NO_STR
2716 MATCH_STR
2717 "Match metric of route\n"
2718 "Metric value\n")
2719
2720DEFUN (match_community,
2721 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002722 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002723 MATCH_STR
2724 "Match BGP community list\n"
2725 "Community-list number (standard)\n"
2726 "Community-list number (expanded)\n"
2727 "Community-list name\n")
2728{
2729 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2730}
2731
2732DEFUN (match_community_exact,
2733 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002734 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002735 MATCH_STR
2736 "Match BGP community list\n"
2737 "Community-list number (standard)\n"
2738 "Community-list number (expanded)\n"
2739 "Community-list name\n"
2740 "Do exact matching of communities\n")
2741{
2742 int ret;
2743 char *argstr;
2744
2745 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2746 strlen (argv[0]) + strlen ("exact-match") + 2);
2747
2748 sprintf (argstr, "%s exact-match", argv[0]);
2749
2750 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2751
2752 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2753
2754 return ret;
2755}
2756
2757DEFUN (no_match_community,
2758 no_match_community_cmd,
2759 "no match community",
2760 NO_STR
2761 MATCH_STR
2762 "Match BGP community list\n")
2763{
2764 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2765}
2766
2767ALIAS (no_match_community,
2768 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002769 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002770 NO_STR
2771 MATCH_STR
2772 "Match BGP community list\n"
2773 "Community-list number (standard)\n"
2774 "Community-list number (expanded)\n"
2775 "Community-list name\n")
2776
2777ALIAS (no_match_community,
2778 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002779 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002780 NO_STR
2781 MATCH_STR
2782 "Match BGP community list\n"
2783 "Community-list number (standard)\n"
2784 "Community-list number (expanded)\n"
2785 "Community-list name\n"
2786 "Do exact matching of communities\n")
2787
paul73ffb252003-04-19 15:49:49 +00002788DEFUN (match_ecommunity,
2789 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002790 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002791 MATCH_STR
2792 "Match BGP/VPN extended community list\n"
2793 "Extended community-list number (standard)\n"
2794 "Extended community-list number (expanded)\n"
2795 "Extended community-list name\n")
2796{
2797 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2798}
2799
2800DEFUN (no_match_ecommunity,
2801 no_match_ecommunity_cmd,
2802 "no match extcommunity",
2803 NO_STR
2804 MATCH_STR
2805 "Match BGP/VPN extended community list\n")
2806{
2807 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2808}
2809
2810ALIAS (no_match_ecommunity,
2811 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002812 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002813 NO_STR
2814 MATCH_STR
2815 "Match BGP/VPN extended community list\n"
2816 "Extended community-list number (standard)\n"
2817 "Extended community-list number (expanded)\n"
2818 "Extended community-list name\n")
2819
paul718e3742002-12-13 20:15:29 +00002820DEFUN (match_aspath,
2821 match_aspath_cmd,
2822 "match as-path WORD",
2823 MATCH_STR
2824 "Match BGP AS path list\n"
2825 "AS path access-list name\n")
2826{
2827 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2828}
2829
2830DEFUN (no_match_aspath,
2831 no_match_aspath_cmd,
2832 "no match as-path",
2833 NO_STR
2834 MATCH_STR
2835 "Match BGP AS path list\n")
2836{
2837 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2838}
2839
2840ALIAS (no_match_aspath,
2841 no_match_aspath_val_cmd,
2842 "no match as-path WORD",
2843 NO_STR
2844 MATCH_STR
2845 "Match BGP AS path list\n"
2846 "AS path access-list name\n")
2847
2848DEFUN (match_origin,
2849 match_origin_cmd,
2850 "match origin (egp|igp|incomplete)",
2851 MATCH_STR
2852 "BGP origin code\n"
2853 "remote EGP\n"
2854 "local IGP\n"
2855 "unknown heritage\n")
2856{
2857 if (strncmp (argv[0], "igp", 2) == 0)
2858 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2859 if (strncmp (argv[0], "egp", 1) == 0)
2860 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2861 if (strncmp (argv[0], "incomplete", 2) == 0)
2862 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2863
2864 return CMD_WARNING;
2865}
2866
2867DEFUN (no_match_origin,
2868 no_match_origin_cmd,
2869 "no match origin",
2870 NO_STR
2871 MATCH_STR
2872 "BGP origin code\n")
2873{
2874 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2875}
2876
2877ALIAS (no_match_origin,
2878 no_match_origin_val_cmd,
2879 "no match origin (egp|igp|incomplete)",
2880 NO_STR
2881 MATCH_STR
2882 "BGP origin code\n"
2883 "remote EGP\n"
2884 "local IGP\n"
2885 "unknown heritage\n")
2886
2887DEFUN (set_ip_nexthop,
2888 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002889 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002890 SET_STR
2891 IP_STR
2892 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002893 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002894{
2895 union sockunion su;
2896 int ret;
2897
2898 ret = str2sockunion (argv[0], &su);
2899 if (ret < 0)
2900 {
2901 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2902 return CMD_WARNING;
2903 }
2904
2905 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2906}
2907
paulaf5cd0a2003-11-02 07:24:40 +00002908DEFUN (set_ip_nexthop_peer,
2909 set_ip_nexthop_peer_cmd,
2910 "set ip next-hop peer-address",
2911 SET_STR
2912 IP_STR
2913 "Next hop address\n"
2914 "Use peer address (for BGP only)\n")
2915{
2916 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2917}
2918
paul94f2b392005-06-28 12:44:16 +00002919DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002920 no_set_ip_nexthop_peer_cmd,
2921 "no set ip next-hop peer-address",
2922 NO_STR
2923 SET_STR
2924 IP_STR
2925 "Next hop address\n"
2926 "Use peer address (for BGP only)\n")
2927{
2928 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2929}
2930
2931
paul718e3742002-12-13 20:15:29 +00002932DEFUN (no_set_ip_nexthop,
2933 no_set_ip_nexthop_cmd,
2934 "no set ip next-hop",
2935 NO_STR
2936 SET_STR
paul718e3742002-12-13 20:15:29 +00002937 "Next hop address\n")
2938{
paulaf5cd0a2003-11-02 07:24:40 +00002939 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002940 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2941
2942 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2943}
2944
2945ALIAS (no_set_ip_nexthop,
2946 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002947 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002948 NO_STR
2949 SET_STR
2950 IP_STR
2951 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002952 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002953
2954DEFUN (set_metric,
2955 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002956 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002957 SET_STR
2958 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002959 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002960{
2961 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2962}
2963
paul73ffb252003-04-19 15:49:49 +00002964ALIAS (set_metric,
2965 set_metric_addsub_cmd,
2966 "set metric <+/-metric>",
2967 SET_STR
2968 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002969 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002970
paul718e3742002-12-13 20:15:29 +00002971DEFUN (no_set_metric,
2972 no_set_metric_cmd,
2973 "no set metric",
2974 NO_STR
2975 SET_STR
2976 "Metric value for destination routing protocol\n")
2977{
2978 if (argc == 0)
2979 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2980
2981 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2982}
2983
2984ALIAS (no_set_metric,
2985 no_set_metric_val_cmd,
2986 "no set metric <0-4294967295>",
2987 NO_STR
2988 SET_STR
2989 "Metric value for destination routing protocol\n"
2990 "Metric value\n")
2991
2992DEFUN (set_local_pref,
2993 set_local_pref_cmd,
2994 "set local-preference <0-4294967295>",
2995 SET_STR
2996 "BGP local preference path attribute\n"
2997 "Preference value\n")
2998{
2999 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3000}
3001
3002DEFUN (no_set_local_pref,
3003 no_set_local_pref_cmd,
3004 "no set local-preference",
3005 NO_STR
3006 SET_STR
3007 "BGP local preference path attribute\n")
3008{
3009 if (argc == 0)
3010 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3011
3012 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3013}
3014
3015ALIAS (no_set_local_pref,
3016 no_set_local_pref_val_cmd,
3017 "no set local-preference <0-4294967295>",
3018 NO_STR
3019 SET_STR
3020 "BGP local preference path attribute\n"
3021 "Preference value\n")
3022
3023DEFUN (set_weight,
3024 set_weight_cmd,
3025 "set weight <0-4294967295>",
3026 SET_STR
3027 "BGP weight for routing table\n"
3028 "Weight value\n")
3029{
3030 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3031}
3032
3033DEFUN (no_set_weight,
3034 no_set_weight_cmd,
3035 "no set weight",
3036 NO_STR
3037 SET_STR
3038 "BGP weight for routing table\n")
3039{
3040 if (argc == 0)
3041 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3042
3043 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3044}
3045
3046ALIAS (no_set_weight,
3047 no_set_weight_val_cmd,
3048 "no set weight <0-4294967295>",
3049 NO_STR
3050 SET_STR
3051 "BGP weight for routing table\n"
3052 "Weight value\n")
3053
3054DEFUN (set_aspath_prepend,
3055 set_aspath_prepend_cmd,
3056 "set as-path prepend .<1-65535>",
3057 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003058 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003059 "Prepend to the as-path\n"
3060 "AS number\n")
3061{
3062 int ret;
3063 char *str;
3064
3065 str = argv_concat (argv, argc, 0);
3066 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3067 XFREE (MTYPE_TMP, str);
3068
3069 return ret;
3070}
3071
3072DEFUN (no_set_aspath_prepend,
3073 no_set_aspath_prepend_cmd,
3074 "no set as-path prepend",
3075 NO_STR
3076 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003077 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003078 "Prepend to the as-path\n")
3079{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003080 int ret;
3081 char *str;
3082
3083 if (argc == 0)
3084 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3085
3086 str = argv_concat (argv, argc, 0);
3087 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3088 XFREE (MTYPE_TMP, str);
3089 return ret;
paul718e3742002-12-13 20:15:29 +00003090}
3091
3092ALIAS (no_set_aspath_prepend,
3093 no_set_aspath_prepend_val_cmd,
3094 "no set as-path prepend .<1-65535>",
3095 NO_STR
3096 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003097 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003098 "Prepend to the as-path\n"
3099 "AS number\n")
3100
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003101DEFUN (set_aspath_exclude,
3102 set_aspath_exclude_cmd,
3103 "set as-path exclude .<1-65535>",
3104 SET_STR
3105 "Transform BGP AS-path attribute\n"
3106 "Exclude from the as-path\n"
3107 "AS number\n")
3108{
3109 int ret;
3110 char *str;
3111
3112 str = argv_concat (argv, argc, 0);
3113 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3114 XFREE (MTYPE_TMP, str);
3115 return ret;
3116}
3117
3118DEFUN (no_set_aspath_exclude,
3119 no_set_aspath_exclude_cmd,
3120 "no set as-path exclude",
3121 NO_STR
3122 SET_STR
3123 "Transform BGP AS_PATH attribute\n"
3124 "Exclude from the as-path\n")
3125{
3126 int ret;
3127 char *str;
3128
3129 if (argc == 0)
3130 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3131
3132 str = argv_concat (argv, argc, 0);
3133 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3134 XFREE (MTYPE_TMP, str);
3135 return ret;
3136}
3137
3138ALIAS (no_set_aspath_exclude,
3139 no_set_aspath_exclude_val_cmd,
3140 "no set as-path exclude .<1-65535>",
3141 NO_STR
3142 SET_STR
3143 "Transform BGP AS_PATH attribute\n"
3144 "Exclude from the as-path\n"
3145 "AS number\n")
3146
paul718e3742002-12-13 20:15:29 +00003147DEFUN (set_community,
3148 set_community_cmd,
3149 "set community .AA:NN",
3150 SET_STR
3151 "BGP community attribute\n"
3152 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3153{
3154 int i;
3155 int first = 0;
3156 int additive = 0;
3157 struct buffer *b;
3158 struct community *com = NULL;
3159 char *str;
3160 char *argstr;
3161 int ret;
3162
3163 b = buffer_new (1024);
3164
3165 for (i = 0; i < argc; i++)
3166 {
3167 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3168 {
3169 additive = 1;
3170 continue;
3171 }
3172
3173 if (first)
3174 buffer_putc (b, ' ');
3175 else
3176 first = 1;
3177
3178 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3179 {
3180 buffer_putstr (b, "internet");
3181 continue;
3182 }
3183 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3184 {
3185 buffer_putstr (b, "local-AS");
3186 continue;
3187 }
3188 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3189 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3190 {
3191 buffer_putstr (b, "no-advertise");
3192 continue;
3193 }
3194 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3195 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3196 {
3197 buffer_putstr (b, "no-export");
3198 continue;
3199 }
3200 buffer_putstr (b, argv[i]);
3201 }
3202 buffer_putc (b, '\0');
3203
3204 /* Fetch result string then compile it to communities attribute. */
3205 str = buffer_getstr (b);
3206 buffer_free (b);
3207
3208 if (str)
3209 {
3210 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003211 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003212 }
3213
3214 /* Can't compile user input into communities attribute. */
3215 if (! com)
3216 {
3217 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3218 return CMD_WARNING;
3219 }
3220
3221 /* Set communites attribute string. */
3222 str = community_str (com);
3223
3224 if (additive)
3225 {
3226 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3227 strcpy (argstr, str);
3228 strcpy (argstr + strlen (str), " additive");
3229 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3230 XFREE (MTYPE_TMP, argstr);
3231 }
3232 else
3233 ret = bgp_route_set_add (vty, vty->index, "community", str);
3234
3235 community_free (com);
3236
3237 return ret;
3238}
3239
3240DEFUN (set_community_none,
3241 set_community_none_cmd,
3242 "set community none",
3243 SET_STR
3244 "BGP community attribute\n"
3245 "No community attribute\n")
3246{
3247 return bgp_route_set_add (vty, vty->index, "community", "none");
3248}
3249
3250DEFUN (no_set_community,
3251 no_set_community_cmd,
3252 "no set community",
3253 NO_STR
3254 SET_STR
3255 "BGP community attribute\n")
3256{
3257 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3258}
3259
3260ALIAS (no_set_community,
3261 no_set_community_val_cmd,
3262 "no set community .AA:NN",
3263 NO_STR
3264 SET_STR
3265 "BGP community attribute\n"
3266 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3267
3268ALIAS (no_set_community,
3269 no_set_community_none_cmd,
3270 "no set community none",
3271 NO_STR
3272 SET_STR
3273 "BGP community attribute\n"
3274 "No community attribute\n")
3275
3276DEFUN (set_community_delete,
3277 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003278 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003279 SET_STR
3280 "set BGP community list (for deletion)\n"
3281 "Community-list number (standard)\n"
3282 "Communitly-list number (expanded)\n"
3283 "Community-list name\n"
3284 "Delete matching communities\n")
3285{
3286 char *str;
3287
3288 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3289 strcpy (str, argv[0]);
3290 strcpy (str + strlen (argv[0]), " delete");
3291
3292 bgp_route_set_add (vty, vty->index, "comm-list", str);
3293
3294 XFREE (MTYPE_TMP, str);
3295 return CMD_SUCCESS;
3296}
3297
3298DEFUN (no_set_community_delete,
3299 no_set_community_delete_cmd,
3300 "no set comm-list",
3301 NO_STR
3302 SET_STR
3303 "set BGP community list (for deletion)\n")
3304{
3305 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3306}
3307
3308ALIAS (no_set_community_delete,
3309 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003310 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003311 NO_STR
3312 SET_STR
3313 "set BGP community list (for deletion)\n"
3314 "Community-list number (standard)\n"
3315 "Communitly-list number (expanded)\n"
3316 "Community-list name\n"
3317 "Delete matching communities\n")
3318
3319DEFUN (set_ecommunity_rt,
3320 set_ecommunity_rt_cmd,
3321 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3322 SET_STR
3323 "BGP extended community attribute\n"
3324 "Route Target extened communityt\n"
3325 "VPN extended community\n")
3326{
3327 int ret;
3328 char *str;
3329
3330 str = argv_concat (argv, argc, 0);
3331 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3332 XFREE (MTYPE_TMP, str);
3333
3334 return ret;
3335}
3336
3337DEFUN (no_set_ecommunity_rt,
3338 no_set_ecommunity_rt_cmd,
3339 "no set extcommunity rt",
3340 NO_STR
3341 SET_STR
3342 "BGP extended community attribute\n"
3343 "Route Target extened communityt\n")
3344{
3345 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3346}
3347
3348ALIAS (no_set_ecommunity_rt,
3349 no_set_ecommunity_rt_val_cmd,
3350 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3351 NO_STR
3352 SET_STR
3353 "BGP extended community attribute\n"
3354 "Route Target extened communityt\n"
3355 "VPN extended community\n")
3356
3357DEFUN (set_ecommunity_soo,
3358 set_ecommunity_soo_cmd,
3359 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3360 SET_STR
3361 "BGP extended community attribute\n"
3362 "Site-of-Origin extended community\n"
3363 "VPN extended community\n")
3364{
3365 int ret;
3366 char *str;
3367
3368 str = argv_concat (argv, argc, 0);
3369 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3370 XFREE (MTYPE_TMP, str);
3371 return ret;
3372}
3373
3374DEFUN (no_set_ecommunity_soo,
3375 no_set_ecommunity_soo_cmd,
3376 "no set extcommunity soo",
3377 NO_STR
3378 SET_STR
3379 "BGP extended community attribute\n"
3380 "Site-of-Origin extended community\n")
3381{
3382 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3383}
3384
3385ALIAS (no_set_ecommunity_soo,
3386 no_set_ecommunity_soo_val_cmd,
3387 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3388 NO_STR
3389 SET_STR
3390 "BGP extended community attribute\n"
3391 "Site-of-Origin extended community\n"
3392 "VPN extended community\n")
3393
3394DEFUN (set_origin,
3395 set_origin_cmd,
3396 "set origin (egp|igp|incomplete)",
3397 SET_STR
3398 "BGP origin code\n"
3399 "remote EGP\n"
3400 "local IGP\n"
3401 "unknown heritage\n")
3402{
3403 if (strncmp (argv[0], "igp", 2) == 0)
3404 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3405 if (strncmp (argv[0], "egp", 1) == 0)
3406 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3407 if (strncmp (argv[0], "incomplete", 2) == 0)
3408 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3409
3410 return CMD_WARNING;
3411}
3412
3413DEFUN (no_set_origin,
3414 no_set_origin_cmd,
3415 "no set origin",
3416 NO_STR
3417 SET_STR
3418 "BGP origin code\n")
3419{
3420 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3421}
3422
3423ALIAS (no_set_origin,
3424 no_set_origin_val_cmd,
3425 "no set origin (egp|igp|incomplete)",
3426 NO_STR
3427 SET_STR
3428 "BGP origin code\n"
3429 "remote EGP\n"
3430 "local IGP\n"
3431 "unknown heritage\n")
3432
3433DEFUN (set_atomic_aggregate,
3434 set_atomic_aggregate_cmd,
3435 "set atomic-aggregate",
3436 SET_STR
3437 "BGP atomic aggregate attribute\n" )
3438{
3439 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3440}
3441
3442DEFUN (no_set_atomic_aggregate,
3443 no_set_atomic_aggregate_cmd,
3444 "no set atomic-aggregate",
3445 NO_STR
3446 SET_STR
3447 "BGP atomic aggregate attribute\n" )
3448{
3449 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3450}
3451
3452DEFUN (set_aggregator_as,
3453 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003454 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003455 SET_STR
3456 "BGP aggregator attribute\n"
3457 "AS number of aggregator\n"
3458 "AS number\n"
3459 "IP address of aggregator\n")
3460{
3461 int ret;
3462 as_t as;
3463 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003464 char *argstr;
3465
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003466 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003467
paul718e3742002-12-13 20:15:29 +00003468 ret = inet_aton (argv[1], &address);
3469 if (ret == 0)
3470 {
3471 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3472 return CMD_WARNING;
3473 }
3474
3475 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3476 strlen (argv[0]) + strlen (argv[1]) + 2);
3477
3478 sprintf (argstr, "%s %s", argv[0], argv[1]);
3479
3480 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3481
3482 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3483
3484 return ret;
3485}
3486
3487DEFUN (no_set_aggregator_as,
3488 no_set_aggregator_as_cmd,
3489 "no set aggregator as",
3490 NO_STR
3491 SET_STR
3492 "BGP aggregator attribute\n"
3493 "AS number of aggregator\n")
3494{
3495 int ret;
3496 as_t as;
3497 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003498 char *argstr;
3499
3500 if (argv == 0)
3501 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3502
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003503 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003504
3505 ret = inet_aton (argv[1], &address);
3506 if (ret == 0)
3507 {
3508 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3509 return CMD_WARNING;
3510 }
3511
3512 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3513 strlen (argv[0]) + strlen (argv[1]) + 2);
3514
3515 sprintf (argstr, "%s %s", argv[0], argv[1]);
3516
3517 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3518
3519 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3520
3521 return ret;
3522}
3523
3524ALIAS (no_set_aggregator_as,
3525 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003526 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003527 NO_STR
3528 SET_STR
3529 "BGP aggregator attribute\n"
3530 "AS number of aggregator\n"
3531 "AS number\n"
3532 "IP address of aggregator\n")
3533
3534
3535#ifdef HAVE_IPV6
3536DEFUN (match_ipv6_address,
3537 match_ipv6_address_cmd,
3538 "match ipv6 address WORD",
3539 MATCH_STR
3540 IPV6_STR
3541 "Match IPv6 address of route\n"
3542 "IPv6 access-list name\n")
3543{
3544 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3545}
3546
3547DEFUN (no_match_ipv6_address,
3548 no_match_ipv6_address_cmd,
3549 "no match ipv6 address WORD",
3550 NO_STR
3551 MATCH_STR
3552 IPV6_STR
3553 "Match IPv6 address of route\n"
3554 "IPv6 access-list name\n")
3555{
3556 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3557}
3558
3559DEFUN (match_ipv6_next_hop,
3560 match_ipv6_next_hop_cmd,
3561 "match ipv6 next-hop X:X::X:X",
3562 MATCH_STR
3563 IPV6_STR
3564 "Match IPv6 next-hop address of route\n"
3565 "IPv6 address of next hop\n")
3566{
3567 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3568}
3569
3570DEFUN (no_match_ipv6_next_hop,
3571 no_match_ipv6_next_hop_cmd,
3572 "no match ipv6 next-hop X:X::X:X",
3573 NO_STR
3574 MATCH_STR
3575 IPV6_STR
3576 "Match IPv6 next-hop address of route\n"
3577 "IPv6 address of next hop\n")
3578{
3579 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3580}
3581
3582DEFUN (match_ipv6_address_prefix_list,
3583 match_ipv6_address_prefix_list_cmd,
3584 "match ipv6 address prefix-list WORD",
3585 MATCH_STR
3586 IPV6_STR
3587 "Match address of route\n"
3588 "Match entries of prefix-lists\n"
3589 "IP prefix-list name\n")
3590{
3591 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3592}
3593
3594DEFUN (no_match_ipv6_address_prefix_list,
3595 no_match_ipv6_address_prefix_list_cmd,
3596 "no match ipv6 address prefix-list WORD",
3597 NO_STR
3598 MATCH_STR
3599 IPV6_STR
3600 "Match address of route\n"
3601 "Match entries of prefix-lists\n"
3602 "IP prefix-list name\n")
3603{
3604 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3605}
3606
3607DEFUN (set_ipv6_nexthop_global,
3608 set_ipv6_nexthop_global_cmd,
3609 "set ipv6 next-hop global X:X::X:X",
3610 SET_STR
3611 IPV6_STR
3612 "IPv6 next-hop address\n"
3613 "IPv6 global address\n"
3614 "IPv6 address of next hop\n")
3615{
3616 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3617}
3618
3619DEFUN (no_set_ipv6_nexthop_global,
3620 no_set_ipv6_nexthop_global_cmd,
3621 "no set ipv6 next-hop global",
3622 NO_STR
3623 SET_STR
3624 IPV6_STR
3625 "IPv6 next-hop address\n"
3626 "IPv6 global address\n")
3627{
3628 if (argc == 0)
3629 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3630
3631 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3632}
3633
3634ALIAS (no_set_ipv6_nexthop_global,
3635 no_set_ipv6_nexthop_global_val_cmd,
3636 "no set ipv6 next-hop global X:X::X:X",
3637 NO_STR
3638 SET_STR
3639 IPV6_STR
3640 "IPv6 next-hop address\n"
3641 "IPv6 global address\n"
3642 "IPv6 address of next hop\n")
3643
3644DEFUN (set_ipv6_nexthop_local,
3645 set_ipv6_nexthop_local_cmd,
3646 "set ipv6 next-hop local X:X::X:X",
3647 SET_STR
3648 IPV6_STR
3649 "IPv6 next-hop address\n"
3650 "IPv6 local address\n"
3651 "IPv6 address of next hop\n")
3652{
3653 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3654}
3655
3656DEFUN (no_set_ipv6_nexthop_local,
3657 no_set_ipv6_nexthop_local_cmd,
3658 "no set ipv6 next-hop local",
3659 NO_STR
3660 SET_STR
3661 IPV6_STR
3662 "IPv6 next-hop address\n"
3663 "IPv6 local address\n")
3664{
3665 if (argc == 0)
3666 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3667
3668 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3669}
3670
3671ALIAS (no_set_ipv6_nexthop_local,
3672 no_set_ipv6_nexthop_local_val_cmd,
3673 "no set ipv6 next-hop local X:X::X:X",
3674 NO_STR
3675 SET_STR
3676 IPV6_STR
3677 "IPv6 next-hop address\n"
3678 "IPv6 local address\n"
3679 "IPv6 address of next hop\n")
3680#endif /* HAVE_IPV6 */
3681
3682DEFUN (set_vpnv4_nexthop,
3683 set_vpnv4_nexthop_cmd,
3684 "set vpnv4 next-hop A.B.C.D",
3685 SET_STR
3686 "VPNv4 information\n"
3687 "VPNv4 next-hop address\n"
3688 "IP address of next hop\n")
3689{
3690 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3691}
3692
3693DEFUN (no_set_vpnv4_nexthop,
3694 no_set_vpnv4_nexthop_cmd,
3695 "no set vpnv4 next-hop",
3696 NO_STR
3697 SET_STR
3698 "VPNv4 information\n"
3699 "VPNv4 next-hop address\n")
3700{
3701 if (argc == 0)
3702 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3703
3704 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3705}
3706
3707ALIAS (no_set_vpnv4_nexthop,
3708 no_set_vpnv4_nexthop_val_cmd,
3709 "no set vpnv4 next-hop A.B.C.D",
3710 NO_STR
3711 SET_STR
3712 "VPNv4 information\n"
3713 "VPNv4 next-hop address\n"
3714 "IP address of next hop\n")
3715
3716DEFUN (set_originator_id,
3717 set_originator_id_cmd,
3718 "set originator-id A.B.C.D",
3719 SET_STR
3720 "BGP originator ID attribute\n"
3721 "IP address of originator\n")
3722{
3723 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3724}
3725
3726DEFUN (no_set_originator_id,
3727 no_set_originator_id_cmd,
3728 "no set originator-id",
3729 NO_STR
3730 SET_STR
3731 "BGP originator ID attribute\n")
3732{
3733 if (argc == 0)
3734 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3735
3736 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3737}
3738
3739ALIAS (no_set_originator_id,
3740 no_set_originator_id_val_cmd,
3741 "no set originator-id A.B.C.D",
3742 NO_STR
3743 SET_STR
3744 "BGP originator ID attribute\n"
3745 "IP address of originator\n")
3746
Paul Jakma41367172007-08-06 15:24:51 +00003747DEFUN (set_pathlimit_ttl,
3748 set_pathlimit_ttl_cmd,
3749 "set pathlimit ttl <1-255>",
3750 SET_STR
3751 "BGP AS-Pathlimit attribute\n"
3752 "Set AS-Path Hop-count TTL\n")
3753{
3754 return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]);
3755}
3756
3757DEFUN (no_set_pathlimit_ttl,
3758 no_set_pathlimit_ttl_cmd,
3759 "no set pathlimit ttl",
3760 NO_STR
3761 SET_STR
3762 "BGP AS-Pathlimit attribute\n"
3763 "Set AS-Path Hop-count TTL\n")
3764{
3765 if (argc == 0)
3766 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL);
3767
3768 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]);
3769}
3770
3771ALIAS (no_set_pathlimit_ttl,
3772 no_set_pathlimit_ttl_val_cmd,
3773 "no set pathlimit ttl <1-255>",
3774 NO_STR
3775 MATCH_STR
3776 "BGP AS-Pathlimit attribute\n"
3777 "Set AS-Path Hop-count TTL\n")
3778
3779DEFUN (match_pathlimit_as,
3780 match_pathlimit_as_cmd,
3781 "match pathlimit as <1-65535>",
3782 MATCH_STR
3783 "BGP AS-Pathlimit attribute\n"
3784 "Match Pathlimit AS number\n")
3785{
3786 return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]);
3787}
3788
3789DEFUN (no_match_pathlimit_as,
3790 no_match_pathlimit_as_cmd,
3791 "no match pathlimit as",
3792 NO_STR
3793 MATCH_STR
3794 "BGP AS-Pathlimit attribute\n"
3795 "Match Pathlimit AS number\n")
3796{
3797 if (argc == 0)
3798 return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL);
3799
3800 return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]);
3801}
3802
3803ALIAS (no_match_pathlimit_as,
3804 no_match_pathlimit_as_val_cmd,
3805 "no match pathlimit as <1-65535>",
3806 NO_STR
3807 MATCH_STR
3808 "BGP AS-Pathlimit attribute\n"
3809 "Match Pathlimit ASN\n")
3810
paul718e3742002-12-13 20:15:29 +00003811
3812/* Initialization of route map. */
3813void
paul94f2b392005-06-28 12:44:16 +00003814bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003815{
3816 route_map_init ();
3817 route_map_init_vty ();
3818 route_map_add_hook (bgp_route_map_update);
3819 route_map_delete_hook (bgp_route_map_update);
3820
paulfee0f4c2004-09-13 05:12:46 +00003821 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003822 route_map_install_match (&route_match_ip_address_cmd);
3823 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003824 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003825 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3826 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003827 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003828 route_map_install_match (&route_match_aspath_cmd);
3829 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003830 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003831 route_map_install_match (&route_match_metric_cmd);
3832 route_map_install_match (&route_match_origin_cmd);
3833
3834 route_map_install_set (&route_set_ip_nexthop_cmd);
3835 route_map_install_set (&route_set_local_pref_cmd);
3836 route_map_install_set (&route_set_weight_cmd);
3837 route_map_install_set (&route_set_metric_cmd);
3838 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003839 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003840 route_map_install_set (&route_set_origin_cmd);
3841 route_map_install_set (&route_set_atomic_aggregate_cmd);
3842 route_map_install_set (&route_set_aggregator_as_cmd);
3843 route_map_install_set (&route_set_community_cmd);
3844 route_map_install_set (&route_set_community_delete_cmd);
3845 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3846 route_map_install_set (&route_set_originator_id_cmd);
3847 route_map_install_set (&route_set_ecommunity_rt_cmd);
3848 route_map_install_set (&route_set_ecommunity_soo_cmd);
3849
paulfee0f4c2004-09-13 05:12:46 +00003850 install_element (RMAP_NODE, &match_peer_cmd);
3851 install_element (RMAP_NODE, &match_peer_local_cmd);
3852 install_element (RMAP_NODE, &no_match_peer_cmd);
3853 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3854 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003855 install_element (RMAP_NODE, &match_ip_address_cmd);
3856 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3857 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3858 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3859 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3860 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003861 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3862 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3863 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003864
3865 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3866 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3867 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3868 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3869 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3870 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003871 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3872 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3873 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003874
3875 install_element (RMAP_NODE, &match_aspath_cmd);
3876 install_element (RMAP_NODE, &no_match_aspath_cmd);
3877 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3878 install_element (RMAP_NODE, &match_metric_cmd);
3879 install_element (RMAP_NODE, &no_match_metric_cmd);
3880 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3881 install_element (RMAP_NODE, &match_community_cmd);
3882 install_element (RMAP_NODE, &match_community_exact_cmd);
3883 install_element (RMAP_NODE, &no_match_community_cmd);
3884 install_element (RMAP_NODE, &no_match_community_val_cmd);
3885 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003886 install_element (RMAP_NODE, &match_ecommunity_cmd);
3887 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3888 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003889 install_element (RMAP_NODE, &match_origin_cmd);
3890 install_element (RMAP_NODE, &no_match_origin_cmd);
3891 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3892
3893 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003894 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003895 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3896 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3897 install_element (RMAP_NODE, &set_local_pref_cmd);
3898 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3899 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3900 install_element (RMAP_NODE, &set_weight_cmd);
3901 install_element (RMAP_NODE, &no_set_weight_cmd);
3902 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3903 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003904 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003905 install_element (RMAP_NODE, &no_set_metric_cmd);
3906 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3907 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003908 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003909 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3910 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003911 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3912 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003913 install_element (RMAP_NODE, &set_origin_cmd);
3914 install_element (RMAP_NODE, &no_set_origin_cmd);
3915 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3916 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3917 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3918 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3919 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3920 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3921 install_element (RMAP_NODE, &set_community_cmd);
3922 install_element (RMAP_NODE, &set_community_none_cmd);
3923 install_element (RMAP_NODE, &no_set_community_cmd);
3924 install_element (RMAP_NODE, &no_set_community_val_cmd);
3925 install_element (RMAP_NODE, &no_set_community_none_cmd);
3926 install_element (RMAP_NODE, &set_community_delete_cmd);
3927 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3928 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3929 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3930 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3931 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3932 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3933 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3934 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3935 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3936 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3937 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3938 install_element (RMAP_NODE, &set_originator_id_cmd);
3939 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3940 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3941
3942#ifdef HAVE_IPV6
3943 route_map_install_match (&route_match_ipv6_address_cmd);
3944 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3945 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3946 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3947 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003948
paul718e3742002-12-13 20:15:29 +00003949 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3950 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3951 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3952 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3953 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3954 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3955 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3956 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3957 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3958 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3959 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3960 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3961#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003962
3963 /* AS-Pathlimit */
3964 route_map_install_match (&route_match_pathlimit_as_cmd);
3965 route_map_install_set (&route_set_pathlimit_ttl_cmd);
3966
3967 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3968 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3969 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3970 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3971 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3972 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003973}