blob: 78ad3f083648775b3b0ae5bd9d1eb677752fcac8 [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;
248
249 return RMAP_NOMATCH;
250 }
251 }
252 }
253 return RMAP_NOMATCH;
254}
255
paul94f2b392005-06-28 12:44:16 +0000256static void *
paulfd79ac92004-10-13 05:06:08 +0000257route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000258{
259 union sockunion *su;
260 int ret;
261
262 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
263
264 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
265 if (ret < 0) {
266 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
267 return NULL;
268 }
269
270 return su;
271}
272
273/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000274static void
paulfee0f4c2004-09-13 05:12:46 +0000275route_match_peer_free (void *rule)
276{
277 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
278}
279
280/* Route map commands for ip address matching. */
281struct route_map_rule_cmd route_match_peer_cmd =
282{
283 "peer",
284 route_match_peer,
285 route_match_peer_compile,
286 route_match_peer_free
287};
288
paul718e3742002-12-13 20:15:29 +0000289/* `match ip address IP_ACCESS_LIST' */
290
291/* Match function should return 1 if match is success else return
292 zero. */
paul94f2b392005-06-28 12:44:16 +0000293static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000294route_match_ip_address (void *rule, struct prefix *prefix,
295 route_map_object_t type, void *object)
296{
297 struct access_list *alist;
298 /* struct prefix_ipv4 match; */
299
300 if (type == RMAP_BGP)
301 {
302 alist = access_list_lookup (AFI_IP, (char *) rule);
303 if (alist == NULL)
304 return RMAP_NOMATCH;
305
306 return (access_list_apply (alist, prefix) == FILTER_DENY ?
307 RMAP_NOMATCH : RMAP_MATCH);
308 }
309 return RMAP_NOMATCH;
310}
311
312/* Route map `ip address' match statement. `arg' should be
313 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000314static void *
paulfd79ac92004-10-13 05:06:08 +0000315route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000316{
317 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
318}
319
320/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000321static void
paul718e3742002-12-13 20:15:29 +0000322route_match_ip_address_free (void *rule)
323{
324 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
325}
326
327/* Route map commands for ip address matching. */
328struct route_map_rule_cmd route_match_ip_address_cmd =
329{
330 "ip address",
331 route_match_ip_address,
332 route_match_ip_address_compile,
333 route_match_ip_address_free
334};
335
336/* `match ip next-hop IP_ADDRESS' */
337
338/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000339static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000340route_match_ip_next_hop (void *rule, struct prefix *prefix,
341 route_map_object_t type, void *object)
342{
343 struct access_list *alist;
344 struct bgp_info *bgp_info;
345 struct prefix_ipv4 p;
346
347 if (type == RMAP_BGP)
348 {
349 bgp_info = object;
350 p.family = AF_INET;
351 p.prefix = bgp_info->attr->nexthop;
352 p.prefixlen = IPV4_MAX_BITLEN;
353
354 alist = access_list_lookup (AFI_IP, (char *) rule);
355 if (alist == NULL)
356 return RMAP_NOMATCH;
357
358 return (access_list_apply (alist, &p) == FILTER_DENY ?
359 RMAP_NOMATCH : RMAP_MATCH);
360 }
361 return RMAP_NOMATCH;
362}
363
364/* Route map `ip next-hop' match statement. `arg' is
365 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000366static void *
paulfd79ac92004-10-13 05:06:08 +0000367route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000368{
369 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
370}
371
372/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000373static void
paul718e3742002-12-13 20:15:29 +0000374route_match_ip_next_hop_free (void *rule)
375{
376 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
377}
378
379/* Route map commands for ip next-hop matching. */
380struct route_map_rule_cmd route_match_ip_next_hop_cmd =
381{
382 "ip next-hop",
383 route_match_ip_next_hop,
384 route_match_ip_next_hop_compile,
385 route_match_ip_next_hop_free
386};
387
hassoc1643bb2005-02-02 16:43:17 +0000388/* `match ip route-source ACCESS-LIST' */
389
390/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000391static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000392route_match_ip_route_source (void *rule, struct prefix *prefix,
393 route_map_object_t type, void *object)
394{
395 struct access_list *alist;
396 struct bgp_info *bgp_info;
397 struct peer *peer;
398 struct prefix_ipv4 p;
399
400 if (type == RMAP_BGP)
401 {
402 bgp_info = object;
403 peer = bgp_info->peer;
404
405 if (! peer || sockunion_family (&peer->su) != AF_INET)
406 return RMAP_NOMATCH;
407
408 p.family = AF_INET;
409 p.prefix = peer->su.sin.sin_addr;
410 p.prefixlen = IPV4_MAX_BITLEN;
411
412 alist = access_list_lookup (AFI_IP, (char *) rule);
413 if (alist == NULL)
414 return RMAP_NOMATCH;
415
416 return (access_list_apply (alist, &p) == FILTER_DENY ?
417 RMAP_NOMATCH : RMAP_MATCH);
418 }
419 return RMAP_NOMATCH;
420}
421
422/* Route map `ip route-source' match statement. `arg' is
423 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000424static void *
hassoc1643bb2005-02-02 16:43:17 +0000425route_match_ip_route_source_compile (const char *arg)
426{
427 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
428}
429
430/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000431static void
hassoc1643bb2005-02-02 16:43:17 +0000432route_match_ip_route_source_free (void *rule)
433{
434 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
435}
436
437/* Route map commands for ip route-source matching. */
438struct route_map_rule_cmd route_match_ip_route_source_cmd =
439{
440 "ip route-source",
441 route_match_ip_route_source,
442 route_match_ip_route_source_compile,
443 route_match_ip_route_source_free
444};
445
paul718e3742002-12-13 20:15:29 +0000446/* `match ip address prefix-list PREFIX_LIST' */
447
paul94f2b392005-06-28 12:44:16 +0000448static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000449route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
450 route_map_object_t type, void *object)
451{
452 struct prefix_list *plist;
453
454 if (type == RMAP_BGP)
455 {
456 plist = prefix_list_lookup (AFI_IP, (char *) rule);
457 if (plist == NULL)
458 return RMAP_NOMATCH;
459
460 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
461 RMAP_NOMATCH : RMAP_MATCH);
462 }
463 return RMAP_NOMATCH;
464}
465
paul94f2b392005-06-28 12:44:16 +0000466static void *
paulfd79ac92004-10-13 05:06:08 +0000467route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000468{
469 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
470}
471
paul94f2b392005-06-28 12:44:16 +0000472static void
paul718e3742002-12-13 20:15:29 +0000473route_match_ip_address_prefix_list_free (void *rule)
474{
475 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
476}
477
478struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
479{
480 "ip address prefix-list",
481 route_match_ip_address_prefix_list,
482 route_match_ip_address_prefix_list_compile,
483 route_match_ip_address_prefix_list_free
484};
485
486/* `match ip next-hop prefix-list PREFIX_LIST' */
487
paul94f2b392005-06-28 12:44:16 +0000488static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000489route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
490 route_map_object_t type, void *object)
491{
492 struct prefix_list *plist;
493 struct bgp_info *bgp_info;
494 struct prefix_ipv4 p;
495
496 if (type == RMAP_BGP)
497 {
498 bgp_info = object;
499 p.family = AF_INET;
500 p.prefix = bgp_info->attr->nexthop;
501 p.prefixlen = IPV4_MAX_BITLEN;
502
503 plist = prefix_list_lookup (AFI_IP, (char *) rule);
504 if (plist == NULL)
505 return RMAP_NOMATCH;
506
507 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
508 RMAP_NOMATCH : RMAP_MATCH);
509 }
510 return RMAP_NOMATCH;
511}
512
paul94f2b392005-06-28 12:44:16 +0000513static void *
paulfd79ac92004-10-13 05:06:08 +0000514route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000515{
516 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
517}
518
paul94f2b392005-06-28 12:44:16 +0000519static void
paul718e3742002-12-13 20:15:29 +0000520route_match_ip_next_hop_prefix_list_free (void *rule)
521{
522 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
523}
524
525struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
526{
527 "ip next-hop prefix-list",
528 route_match_ip_next_hop_prefix_list,
529 route_match_ip_next_hop_prefix_list_compile,
530 route_match_ip_next_hop_prefix_list_free
531};
532
hassoc1643bb2005-02-02 16:43:17 +0000533/* `match ip route-source prefix-list PREFIX_LIST' */
534
paul94f2b392005-06-28 12:44:16 +0000535static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000536route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
537 route_map_object_t type, void *object)
538{
539 struct prefix_list *plist;
540 struct bgp_info *bgp_info;
541 struct peer *peer;
542 struct prefix_ipv4 p;
543
544 if (type == RMAP_BGP)
545 {
546 bgp_info = object;
547 peer = bgp_info->peer;
548
549 if (! peer || sockunion_family (&peer->su) != AF_INET)
550 return RMAP_NOMATCH;
551
552 p.family = AF_INET;
553 p.prefix = peer->su.sin.sin_addr;
554 p.prefixlen = IPV4_MAX_BITLEN;
555
556 plist = prefix_list_lookup (AFI_IP, (char *) rule);
557 if (plist == NULL)
558 return RMAP_NOMATCH;
559
560 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
561 RMAP_NOMATCH : RMAP_MATCH);
562 }
563 return RMAP_NOMATCH;
564}
565
paul94f2b392005-06-28 12:44:16 +0000566static void *
hassoc1643bb2005-02-02 16:43:17 +0000567route_match_ip_route_source_prefix_list_compile (const char *arg)
568{
569 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
570}
571
paul94f2b392005-06-28 12:44:16 +0000572static void
hassoc1643bb2005-02-02 16:43:17 +0000573route_match_ip_route_source_prefix_list_free (void *rule)
574{
575 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
576}
577
578struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
579{
580 "ip route-source prefix-list",
581 route_match_ip_route_source_prefix_list,
582 route_match_ip_route_source_prefix_list_compile,
583 route_match_ip_route_source_prefix_list_free
584};
585
paul718e3742002-12-13 20:15:29 +0000586/* `match metric METRIC' */
587
588/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000589static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000590route_match_metric (void *rule, struct prefix *prefix,
591 route_map_object_t type, void *object)
592{
593 u_int32_t *med;
594 struct bgp_info *bgp_info;
595
596 if (type == RMAP_BGP)
597 {
598 med = rule;
599 bgp_info = object;
600
601 if (bgp_info->attr->med == *med)
602 return RMAP_MATCH;
603 else
604 return RMAP_NOMATCH;
605 }
606 return RMAP_NOMATCH;
607}
608
609/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000610static void *
paulfd79ac92004-10-13 05:06:08 +0000611route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000612{
613 u_int32_t *med;
614 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000615 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000616
paul3b424972003-10-13 09:47:32 +0000617 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000618 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000619 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000620
paul718e3742002-12-13 20:15:29 +0000621 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000622
623 if (!med)
624 return med;
625
paul3b424972003-10-13 09:47:32 +0000626 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000627 return med;
628}
629
630/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000631static void
paul718e3742002-12-13 20:15:29 +0000632route_match_metric_free (void *rule)
633{
634 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
635}
636
637/* Route map commands for metric matching. */
638struct route_map_rule_cmd route_match_metric_cmd =
639{
640 "metric",
641 route_match_metric,
642 route_match_metric_compile,
643 route_match_metric_free
644};
645
646/* `match as-path ASPATH' */
647
648/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000649static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000650route_match_aspath (void *rule, struct prefix *prefix,
651 route_map_object_t type, void *object)
652{
653
654 struct as_list *as_list;
655 struct bgp_info *bgp_info;
656
657 if (type == RMAP_BGP)
658 {
659 as_list = as_list_lookup ((char *) rule);
660 if (as_list == NULL)
661 return RMAP_NOMATCH;
662
663 bgp_info = object;
664
665 /* Perform match. */
666 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
667 }
668 return RMAP_NOMATCH;
669}
670
671/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000672static void *
paulfd79ac92004-10-13 05:06:08 +0000673route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000674{
675 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
676}
677
678/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000679static void
paul718e3742002-12-13 20:15:29 +0000680route_match_aspath_free (void *rule)
681{
682 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
683}
684
685/* Route map commands for aspath matching. */
686struct route_map_rule_cmd route_match_aspath_cmd =
687{
688 "as-path",
689 route_match_aspath,
690 route_match_aspath_compile,
691 route_match_aspath_free
692};
paul718e3742002-12-13 20:15:29 +0000693
694/* `match community COMMUNIY' */
695struct rmap_community
696{
697 char *name;
698 int exact;
699};
700
701/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000702static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000703route_match_community (void *rule, struct prefix *prefix,
704 route_map_object_t type, void *object)
705{
706 struct community_list *list;
707 struct bgp_info *bgp_info;
708 struct rmap_community *rcom;
709
710 if (type == RMAP_BGP)
711 {
712 bgp_info = object;
713 rcom = rule;
714
hassofee6e4e2005-02-02 16:29:31 +0000715 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000716 if (! list)
717 return RMAP_NOMATCH;
718
719 if (rcom->exact)
720 {
721 if (community_list_exact_match (bgp_info->attr->community, list))
722 return RMAP_MATCH;
723 }
724 else
725 {
726 if (community_list_match (bgp_info->attr->community, list))
727 return RMAP_MATCH;
728 }
729 }
730 return RMAP_NOMATCH;
731}
732
733/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000734static void *
paulfd79ac92004-10-13 05:06:08 +0000735route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000736{
737 struct rmap_community *rcom;
738 int len;
739 char *p;
740
741 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
742
743 p = strchr (arg, ' ');
744 if (p)
745 {
746 len = p - arg;
747 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
748 memcpy (rcom->name, arg, len);
749 rcom->exact = 1;
750 }
751 else
752 {
753 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
754 rcom->exact = 0;
755 }
756 return rcom;
757}
758
759/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000760static void
paul718e3742002-12-13 20:15:29 +0000761route_match_community_free (void *rule)
762{
763 struct rmap_community *rcom = rule;
764
765 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
766 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
767}
768
769/* Route map commands for community matching. */
770struct route_map_rule_cmd route_match_community_cmd =
771{
772 "community",
773 route_match_community,
774 route_match_community_compile,
775 route_match_community_free
776};
777
paul73ffb252003-04-19 15:49:49 +0000778/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000779static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000780route_match_ecommunity (void *rule, struct prefix *prefix,
781 route_map_object_t type, void *object)
782{
783 struct community_list *list;
784 struct bgp_info *bgp_info;
785
786 if (type == RMAP_BGP)
787 {
788 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000789
790 if (!bgp_info->attr->extra)
791 return RMAP_NOMATCH;
792
paul73ffb252003-04-19 15:49:49 +0000793 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000794 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000795 if (! list)
796 return RMAP_NOMATCH;
797
Paul Jakmafb982c22007-05-04 20:15:47 +0000798 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000799 return RMAP_MATCH;
800 }
801 return RMAP_NOMATCH;
802}
803
804/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000805static void *
paulfd79ac92004-10-13 05:06:08 +0000806route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000807{
808 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
809}
810
811/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000812static void
paul73ffb252003-04-19 15:49:49 +0000813route_match_ecommunity_free (void *rule)
814{
815 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
816}
817
818/* Route map commands for community matching. */
819struct route_map_rule_cmd route_match_ecommunity_cmd =
820{
821 "extcommunity",
822 route_match_ecommunity,
823 route_match_ecommunity_compile,
824 route_match_ecommunity_free
825};
826
paul718e3742002-12-13 20:15:29 +0000827/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
828 and `address-family vpnv4'. */
829
830/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000831static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000832route_match_origin (void *rule, struct prefix *prefix,
833 route_map_object_t type, void *object)
834{
835 u_char *origin;
836 struct bgp_info *bgp_info;
837
838 if (type == RMAP_BGP)
839 {
840 origin = rule;
841 bgp_info = object;
842
843 if (bgp_info->attr->origin == *origin)
844 return RMAP_MATCH;
845 }
846
847 return RMAP_NOMATCH;
848}
849
paul94f2b392005-06-28 12:44:16 +0000850static void *
paulfd79ac92004-10-13 05:06:08 +0000851route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000852{
853 u_char *origin;
854
855 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
856
857 if (strcmp (arg, "igp") == 0)
858 *origin = 0;
859 else if (strcmp (arg, "egp") == 0)
860 *origin = 1;
861 else
862 *origin = 2;
863
864 return origin;
865}
866
867/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000868static void
paul718e3742002-12-13 20:15:29 +0000869route_match_origin_free (void *rule)
870{
871 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
872}
873
874/* Route map commands for origin matching. */
875struct route_map_rule_cmd route_match_origin_cmd =
876{
877 "origin",
878 route_match_origin,
879 route_match_origin_compile,
880 route_match_origin_free
881};
882/* `set ip next-hop IP_ADDRESS' */
883
884/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000885struct rmap_ip_nexthop_set
886{
887 struct in_addr *address;
888 int peer_address;
889};
890
paul94f2b392005-06-28 12:44:16 +0000891static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000892route_set_ip_nexthop (void *rule, struct prefix *prefix,
893 route_map_object_t type, void *object)
894{
paulac41b2a2003-08-12 05:32:27 +0000895 struct rmap_ip_nexthop_set *rins = rule;
896 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000897 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000898 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000899
900 if (type == RMAP_BGP)
901 {
paul718e3742002-12-13 20:15:29 +0000902 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000903 peer = bgp_info->peer;
904
905 if (rins->peer_address)
906 {
paulfee0f4c2004-09-13 05:12:46 +0000907 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
908 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000909 && peer->su_remote
910 && sockunion_family (peer->su_remote) == AF_INET)
911 {
912 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
913 bgp_info->attr->nexthop = peer_address;
914 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
915 }
916 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
917 && peer->su_local
918 && sockunion_family (peer->su_local) == AF_INET)
919 {
920 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
921 bgp_info->attr->nexthop = peer_address;
922 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
923 }
924 }
925 else
926 {
927 /* Set next hop value. */
928 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
929 bgp_info->attr->nexthop = *rins->address;
930 }
paul718e3742002-12-13 20:15:29 +0000931 }
932
933 return RMAP_OKAY;
934}
935
936/* Route map `ip nexthop' compile function. Given string is converted
937 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000938static void *
paulfd79ac92004-10-13 05:06:08 +0000939route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000940{
paulac41b2a2003-08-12 05:32:27 +0000941 struct rmap_ip_nexthop_set *rins;
942 struct in_addr *address = NULL;
943 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000944 int ret;
paul718e3742002-12-13 20:15:29 +0000945
paulac41b2a2003-08-12 05:32:27 +0000946 if (strcmp (arg, "peer-address") == 0)
947 peer_address = 1;
948 else
paul718e3742002-12-13 20:15:29 +0000949 {
paulac41b2a2003-08-12 05:32:27 +0000950 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
951 ret = inet_aton (arg, address);
952
953 if (ret == 0)
954 {
955 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
956 return NULL;
957 }
paul718e3742002-12-13 20:15:29 +0000958 }
959
paulac41b2a2003-08-12 05:32:27 +0000960 rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
961 memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
962
963 rins->address = address;
964 rins->peer_address = peer_address;
965
966 return rins;
paul718e3742002-12-13 20:15:29 +0000967}
968
969/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000970static void
paul718e3742002-12-13 20:15:29 +0000971route_set_ip_nexthop_free (void *rule)
972{
paulac41b2a2003-08-12 05:32:27 +0000973 struct rmap_ip_nexthop_set *rins = rule;
974
975 if (rins->address)
976 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
977
978 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000979}
980
981/* Route map commands for ip nexthop set. */
982struct route_map_rule_cmd route_set_ip_nexthop_cmd =
983{
984 "ip next-hop",
985 route_set_ip_nexthop,
986 route_set_ip_nexthop_compile,
987 route_set_ip_nexthop_free
988};
989
990/* `set local-preference LOCAL_PREF' */
991
992/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000993static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000994route_set_local_pref (void *rule, struct prefix *prefix,
995 route_map_object_t type, void *object)
996{
997 u_int32_t *local_pref;
998 struct bgp_info *bgp_info;
999
1000 if (type == RMAP_BGP)
1001 {
1002 /* Fetch routemap's rule information. */
1003 local_pref = rule;
1004 bgp_info = object;
1005
1006 /* Set local preference value. */
1007 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1008 bgp_info->attr->local_pref = *local_pref;
1009 }
1010
1011 return RMAP_OKAY;
1012}
1013
1014/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001015static void *
paulfd79ac92004-10-13 05:06:08 +00001016route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001017{
paulfd79ac92004-10-13 05:06:08 +00001018 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001019 u_int32_t *local_pref;
1020 char *endptr = NULL;
1021
1022 /* Local preference value shoud be integer. */
1023 if (! all_digit (arg))
1024 return NULL;
paulfd79ac92004-10-13 05:06:08 +00001025
1026 tmp = strtoul (arg, &endptr, 10);
1027 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1028 return NULL;
1029
1030 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1031
1032 if (!local_pref)
1033 return local_pref;
1034
1035 *local_pref = tmp;
1036
paul718e3742002-12-13 20:15:29 +00001037 return local_pref;
1038}
1039
1040/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001041static void
paul718e3742002-12-13 20:15:29 +00001042route_set_local_pref_free (void *rule)
1043{
1044 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1045}
1046
1047/* Set local preference rule structure. */
1048struct route_map_rule_cmd route_set_local_pref_cmd =
1049{
1050 "local-preference",
1051 route_set_local_pref,
1052 route_set_local_pref_compile,
1053 route_set_local_pref_free,
1054};
1055
1056/* `set weight WEIGHT' */
1057
1058/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001059static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001060route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1061 void *object)
1062{
1063 u_int32_t *weight;
1064 struct bgp_info *bgp_info;
1065
1066 if (type == RMAP_BGP)
1067 {
1068 /* Fetch routemap's rule information. */
1069 weight = rule;
1070 bgp_info = object;
1071
1072 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001073 if (*weight)
1074 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1075 else if (bgp_info->attr->extra)
1076 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001077 }
1078
1079 return RMAP_OKAY;
1080}
1081
1082/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001083static void *
paulfd79ac92004-10-13 05:06:08 +00001084route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001085{
paulfd79ac92004-10-13 05:06:08 +00001086 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001087 u_int32_t *weight;
1088 char *endptr = NULL;
1089
1090 /* Local preference value shoud be integer. */
1091 if (! all_digit (arg))
1092 return NULL;
1093
paulfd79ac92004-10-13 05:06:08 +00001094
1095 tmp = strtoul (arg, &endptr, 10);
1096 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1097 return NULL;
1098
paul718e3742002-12-13 20:15:29 +00001099 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001100
1101 if (weight == NULL)
1102 return weight;
1103
1104 *weight = tmp;
1105
paul718e3742002-12-13 20:15:29 +00001106 return weight;
1107}
1108
1109/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001110static void
paul718e3742002-12-13 20:15:29 +00001111route_set_weight_free (void *rule)
1112{
1113 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1114}
1115
1116/* Set local preference rule structure. */
1117struct route_map_rule_cmd route_set_weight_cmd =
1118{
1119 "weight",
1120 route_set_weight,
1121 route_set_weight_compile,
1122 route_set_weight_free,
1123};
1124
1125/* `set metric METRIC' */
1126
1127/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001128static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001129route_set_metric (void *rule, struct prefix *prefix,
1130 route_map_object_t type, void *object)
1131{
1132 char *metric;
1133 u_int32_t metric_val;
1134 struct bgp_info *bgp_info;
1135
1136 if (type == RMAP_BGP)
1137 {
1138 /* Fetch routemap's rule information. */
1139 metric = rule;
1140 bgp_info = object;
1141
1142 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1143 bgp_info->attr->med = 0;
1144 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1145
1146 if (all_digit (metric))
1147 {
1148 metric_val = strtoul (metric, (char **)NULL, 10);
1149 bgp_info->attr->med = metric_val;
1150 }
1151 else
1152 {
1153 metric_val = strtoul (metric+1, (char **)NULL, 10);
1154
1155 if (strncmp (metric, "+", 1) == 0)
1156 {
paul3b424972003-10-13 09:47:32 +00001157 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1158 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001159 else
paul537d8ea2003-08-27 06:45:32 +00001160 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001161 }
1162 else if (strncmp (metric, "-", 1) == 0)
1163 {
paul537d8ea2003-08-27 06:45:32 +00001164 if (bgp_info->attr->med <= metric_val)
1165 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001166 else
paul537d8ea2003-08-27 06:45:32 +00001167 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001168 }
1169 }
1170 }
1171 return RMAP_OKAY;
1172}
1173
1174/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001175static void *
paulfd79ac92004-10-13 05:06:08 +00001176route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001177{
1178 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001179 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001180 char *endptr = NULL;
1181
1182 if (all_digit (arg))
1183 {
1184 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001185 larg = strtoul (arg, &endptr, 10);
1186 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001187 return NULL;
paul94f2b392005-06-28 12:44:16 +00001188 metric = larg;
paul718e3742002-12-13 20:15:29 +00001189 }
1190 else
1191 {
1192 /* set metric +/-value check */
1193 if ((strncmp (arg, "+", 1) != 0
1194 && strncmp (arg, "-", 1) != 0)
1195 || (! all_digit (arg+1)))
1196 return NULL;
1197
paul94f2b392005-06-28 12:44:16 +00001198 larg = strtoul (arg+1, &endptr, 10);
1199 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001200 return NULL;
paul94f2b392005-06-28 12:44:16 +00001201 metric = larg;
paul718e3742002-12-13 20:15:29 +00001202 }
1203
1204 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1205}
1206
1207/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001208static void
paul718e3742002-12-13 20:15:29 +00001209route_set_metric_free (void *rule)
1210{
1211 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1212}
1213
1214/* Set metric rule structure. */
1215struct route_map_rule_cmd route_set_metric_cmd =
1216{
1217 "metric",
1218 route_set_metric,
1219 route_set_metric_compile,
1220 route_set_metric_free,
1221};
1222
1223/* `set as-path prepend ASPATH' */
1224
1225/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001226static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001227route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1228{
1229 struct aspath *aspath;
1230 struct aspath *new;
1231 struct bgp_info *binfo;
1232
1233 if (type == RMAP_BGP)
1234 {
1235 aspath = rule;
1236 binfo = object;
1237
1238 if (binfo->attr->aspath->refcnt)
1239 new = aspath_dup (binfo->attr->aspath);
1240 else
1241 new = binfo->attr->aspath;
1242
1243 aspath_prepend (aspath, new);
1244 binfo->attr->aspath = new;
1245 }
1246
1247 return RMAP_OKAY;
1248}
1249
1250/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001251static void *
paulfd79ac92004-10-13 05:06:08 +00001252route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001253{
1254 struct aspath *aspath;
1255
1256 aspath = aspath_str2aspath (arg);
1257 if (! aspath)
1258 return NULL;
1259 return aspath;
1260}
1261
1262/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001263static void
paul718e3742002-12-13 20:15:29 +00001264route_set_aspath_prepend_free (void *rule)
1265{
1266 struct aspath *aspath = rule;
1267 aspath_free (aspath);
1268}
1269
1270/* Set metric rule structure. */
1271struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1272{
1273 "as-path prepend",
1274 route_set_aspath_prepend,
1275 route_set_aspath_prepend_compile,
1276 route_set_aspath_prepend_free,
1277};
1278
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001279/* `set as-path exclude ASn' */
1280
1281/* For ASN exclude mechanism.
1282 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1283 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1284 */
1285static route_map_result_t
1286route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1287{
1288 struct aspath * new_path, * exclude_path;
1289 struct bgp_info *binfo;
1290
1291 if (type == RMAP_BGP)
1292 {
1293 exclude_path = rule;
1294 binfo = object;
1295 if (binfo->attr->aspath->refcnt)
1296 new_path = aspath_dup (binfo->attr->aspath);
1297 else
1298 new_path = binfo->attr->aspath;
1299 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1300 }
1301 return RMAP_OKAY;
1302}
1303
1304/* FIXME: consider using route_set_aspath_prepend_compile() and
1305 * route_set_aspath_prepend_free(), which two below function are
1306 * exact clones of.
1307 */
1308
1309/* Compile function for as-path exclude. */
1310static void *
1311route_set_aspath_exclude_compile (const char *arg)
1312{
1313 struct aspath *aspath;
1314
1315 aspath = aspath_str2aspath (arg);
1316 if (! aspath)
1317 return NULL;
1318 return aspath;
1319}
1320
1321static void
1322route_set_aspath_exclude_free (void *rule)
1323{
1324 struct aspath *aspath = rule;
1325 aspath_free (aspath);
1326}
1327
1328/* Set ASn exlude rule structure. */
1329struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1330{
1331 "as-path exclude",
1332 route_set_aspath_exclude,
1333 route_set_aspath_exclude_compile,
1334 route_set_aspath_exclude_free,
1335};
1336
paul718e3742002-12-13 20:15:29 +00001337/* `set community COMMUNITY' */
1338struct rmap_com_set
1339{
1340 struct community *com;
1341 int additive;
1342 int none;
1343};
1344
1345/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001346static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001347route_set_community (void *rule, struct prefix *prefix,
1348 route_map_object_t type, void *object)
1349{
1350 struct rmap_com_set *rcs;
1351 struct bgp_info *binfo;
1352 struct attr *attr;
1353 struct community *new = NULL;
1354 struct community *old;
1355 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001356
paul718e3742002-12-13 20:15:29 +00001357 if (type == RMAP_BGP)
1358 {
1359 rcs = rule;
1360 binfo = object;
1361 attr = binfo->attr;
1362 old = attr->community;
1363
1364 /* "none" case. */
1365 if (rcs->none)
1366 {
1367 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1368 attr->community = NULL;
1369 return RMAP_OKAY;
1370 }
1371
1372 /* "additive" case. */
1373 if (rcs->additive && old)
1374 {
1375 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001376
1377 /* HACK: if the old community is not intern'd,
1378 * we should free it here, or all reference to it may be lost.
1379 * Really need to cleanup attribute caching sometime.
1380 */
1381 if (old->refcnt == 0)
1382 community_free (old);
paul718e3742002-12-13 20:15:29 +00001383 new = community_uniq_sort (merge);
1384 community_free (merge);
1385 }
1386 else
1387 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001388
1389 /* will be interned by caller if required */
paul718e3742002-12-13 20:15:29 +00001390 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001391
paul718e3742002-12-13 20:15:29 +00001392 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1393 }
1394
1395 return RMAP_OKAY;
1396}
1397
1398/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001399static void *
paulfd79ac92004-10-13 05:06:08 +00001400route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001401{
1402 struct rmap_com_set *rcs;
1403 struct community *com = NULL;
1404 char *sp;
1405 int additive = 0;
1406 int none = 0;
1407
1408 if (strcmp (arg, "none") == 0)
1409 none = 1;
1410 else
1411 {
1412 sp = strstr (arg, "additive");
1413
1414 if (sp && sp > arg)
1415 {
1416 /* "additive" keyworkd is included. */
1417 additive = 1;
1418 *(sp - 1) = '\0';
1419 }
1420
1421 com = community_str2com (arg);
1422
1423 if (additive)
1424 *(sp - 1) = ' ';
1425
1426 if (! com)
1427 return NULL;
1428 }
1429
1430 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1431 memset (rcs, 0, sizeof (struct rmap_com_set));
1432
1433 rcs->com = com;
1434 rcs->additive = additive;
1435 rcs->none = none;
1436
1437 return rcs;
1438}
1439
1440/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001441static void
paul718e3742002-12-13 20:15:29 +00001442route_set_community_free (void *rule)
1443{
1444 struct rmap_com_set *rcs = rule;
1445
1446 if (rcs->com)
1447 community_free (rcs->com);
1448 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1449}
1450
1451/* Set community rule structure. */
1452struct route_map_rule_cmd route_set_community_cmd =
1453{
1454 "community",
1455 route_set_community,
1456 route_set_community_compile,
1457 route_set_community_free,
1458};
1459
hassofee6e4e2005-02-02 16:29:31 +00001460/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001461
1462/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001463static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001464route_set_community_delete (void *rule, struct prefix *prefix,
1465 route_map_object_t type, void *object)
1466{
1467 struct community_list *list;
1468 struct community *merge;
1469 struct community *new;
1470 struct community *old;
1471 struct bgp_info *binfo;
1472
1473 if (type == RMAP_BGP)
1474 {
1475 if (! rule)
1476 return RMAP_OKAY;
1477
1478 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001479 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001480 old = binfo->attr->community;
1481
1482 if (list && old)
1483 {
1484 merge = community_list_match_delete (community_dup (old), list);
1485 new = community_uniq_sort (merge);
1486 community_free (merge);
1487
1488 if (new->size == 0)
1489 {
1490 binfo->attr->community = NULL;
1491 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1492 community_free (new);
1493 }
1494 else
1495 {
1496 binfo->attr->community = new;
1497 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1498 }
1499 }
1500 }
1501
1502 return RMAP_OKAY;
1503}
1504
1505/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001506static void *
paulfd79ac92004-10-13 05:06:08 +00001507route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001508{
1509 char *p;
1510 char *str;
1511 int len;
1512
1513 p = strchr (arg, ' ');
1514 if (p)
1515 {
1516 len = p - arg;
1517 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1518 memcpy (str, arg, len);
1519 }
1520 else
1521 str = NULL;
1522
1523 return str;
1524}
1525
1526/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001527static void
paul718e3742002-12-13 20:15:29 +00001528route_set_community_delete_free (void *rule)
1529{
1530 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1531}
1532
1533/* Set community rule structure. */
1534struct route_map_rule_cmd route_set_community_delete_cmd =
1535{
1536 "comm-list",
1537 route_set_community_delete,
1538 route_set_community_delete_compile,
1539 route_set_community_delete_free,
1540};
1541
1542/* `set extcommunity rt COMMUNITY' */
1543
1544/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001545static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001546route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1547 route_map_object_t type, void *object)
1548{
1549 struct ecommunity *ecom;
1550 struct ecommunity *new_ecom;
1551 struct ecommunity *old_ecom;
1552 struct bgp_info *bgp_info;
1553
1554 if (type == RMAP_BGP)
1555 {
1556 ecom = rule;
1557 bgp_info = object;
1558
1559 if (! ecom)
1560 return RMAP_OKAY;
1561
1562 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001563 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001564
1565 if (old_ecom)
1566 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1567 else
1568 new_ecom = ecommunity_dup (ecom);
1569
Paul Jakmafb982c22007-05-04 20:15:47 +00001570 bgp_info->attr->extra->ecommunity = new_ecom;
paul718e3742002-12-13 20:15:29 +00001571
hasso70601e02005-05-27 03:26:57 +00001572 if (old_ecom)
1573 ecommunity_free (old_ecom);
1574
paul718e3742002-12-13 20:15:29 +00001575 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1576 }
1577 return RMAP_OKAY;
1578}
1579
1580/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001581static void *
paulfd79ac92004-10-13 05:06:08 +00001582route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001583{
1584 struct ecommunity *ecom;
1585
1586 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1587 if (! ecom)
1588 return NULL;
1589 return ecom;
1590}
1591
1592/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001593static void
paul718e3742002-12-13 20:15:29 +00001594route_set_ecommunity_rt_free (void *rule)
1595{
1596 struct ecommunity *ecom = rule;
1597 ecommunity_free (ecom);
1598}
1599
1600/* Set community rule structure. */
1601struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1602{
1603 "extcommunity rt",
1604 route_set_ecommunity_rt,
1605 route_set_ecommunity_rt_compile,
1606 route_set_ecommunity_rt_free,
1607};
1608
1609/* `set extcommunity soo COMMUNITY' */
1610
1611/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001612static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001613route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1614 route_map_object_t type, void *object)
1615{
1616 struct ecommunity *ecom;
1617 struct bgp_info *bgp_info;
1618
1619 if (type == RMAP_BGP)
1620 {
1621 ecom = rule;
1622 bgp_info = object;
1623
1624 if (! ecom)
1625 return RMAP_OKAY;
1626
1627 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
Paul Jakmafb982c22007-05-04 20:15:47 +00001628 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
paul718e3742002-12-13 20:15:29 +00001629 }
1630 return RMAP_OKAY;
1631}
1632
1633/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001634static void *
paulfd79ac92004-10-13 05:06:08 +00001635route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001636{
1637 struct ecommunity *ecom;
1638
1639 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1640 if (! ecom)
1641 return NULL;
1642
1643 return ecom;
1644}
1645
1646/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001647static void
paul718e3742002-12-13 20:15:29 +00001648route_set_ecommunity_soo_free (void *rule)
1649{
1650 struct ecommunity *ecom = rule;
1651 ecommunity_free (ecom);
1652}
1653
1654/* Set community rule structure. */
1655struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1656{
1657 "extcommunity soo",
1658 route_set_ecommunity_soo,
1659 route_set_ecommunity_soo_compile,
1660 route_set_ecommunity_soo_free,
1661};
1662
1663/* `set origin ORIGIN' */
1664
1665/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001666static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001667route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1668{
1669 u_char *origin;
1670 struct bgp_info *bgp_info;
1671
1672 if (type == RMAP_BGP)
1673 {
1674 origin = rule;
1675 bgp_info = object;
1676
1677 bgp_info->attr->origin = *origin;
1678 }
1679
1680 return RMAP_OKAY;
1681}
1682
1683/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001684static void *
paulfd79ac92004-10-13 05:06:08 +00001685route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001686{
1687 u_char *origin;
1688
1689 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1690
1691 if (strcmp (arg, "igp") == 0)
1692 *origin = 0;
1693 else if (strcmp (arg, "egp") == 0)
1694 *origin = 1;
1695 else
1696 *origin = 2;
1697
1698 return origin;
1699}
1700
1701/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001702static void
paul718e3742002-12-13 20:15:29 +00001703route_set_origin_free (void *rule)
1704{
1705 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1706}
1707
1708/* Set metric rule structure. */
1709struct route_map_rule_cmd route_set_origin_cmd =
1710{
1711 "origin",
1712 route_set_origin,
1713 route_set_origin_compile,
1714 route_set_origin_free,
1715};
1716
1717/* `set atomic-aggregate' */
1718
1719/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001720static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001721route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1722 route_map_object_t type, void *object)
1723{
1724 struct bgp_info *bgp_info;
1725
1726 if (type == RMAP_BGP)
1727 {
1728 bgp_info = object;
1729 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1730 }
1731
1732 return RMAP_OKAY;
1733}
1734
1735/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001736static void *
paulfd79ac92004-10-13 05:06:08 +00001737route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001738{
1739 return (void *)1;
1740}
1741
1742/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001743static void
paul718e3742002-12-13 20:15:29 +00001744route_set_atomic_aggregate_free (void *rule)
1745{
1746 return;
1747}
1748
1749/* Set atomic aggregate rule structure. */
1750struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1751{
1752 "atomic-aggregate",
1753 route_set_atomic_aggregate,
1754 route_set_atomic_aggregate_compile,
1755 route_set_atomic_aggregate_free,
1756};
1757
1758/* `set aggregator as AS A.B.C.D' */
1759struct aggregator
1760{
1761 as_t as;
1762 struct in_addr address;
1763};
1764
paul94f2b392005-06-28 12:44:16 +00001765static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001766route_set_aggregator_as (void *rule, struct prefix *prefix,
1767 route_map_object_t type, void *object)
1768{
1769 struct bgp_info *bgp_info;
1770 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001771 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001772
1773 if (type == RMAP_BGP)
1774 {
1775 bgp_info = object;
1776 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001777 ae = bgp_attr_extra_get (bgp_info->attr);
1778
1779 ae->aggregator_as = aggregator->as;
1780 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001781 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1782 }
1783
1784 return RMAP_OKAY;
1785}
1786
paul94f2b392005-06-28 12:44:16 +00001787static void *
paulfd79ac92004-10-13 05:06:08 +00001788route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001789{
1790 struct aggregator *aggregator;
1791 char as[10];
1792 char address[20];
1793
1794 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1795 memset (aggregator, 0, sizeof (struct aggregator));
1796
1797 sscanf (arg, "%s %s", as, address);
1798
1799 aggregator->as = strtoul (as, NULL, 10);
1800 inet_aton (address, &aggregator->address);
1801
1802 return aggregator;
1803}
1804
paul94f2b392005-06-28 12:44:16 +00001805static void
paul718e3742002-12-13 20:15:29 +00001806route_set_aggregator_as_free (void *rule)
1807{
1808 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1809}
1810
1811struct route_map_rule_cmd route_set_aggregator_as_cmd =
1812{
1813 "aggregator as",
1814 route_set_aggregator_as,
1815 route_set_aggregator_as_compile,
1816 route_set_aggregator_as_free,
1817};
1818
1819#ifdef HAVE_IPV6
1820/* `match ipv6 address IP_ACCESS_LIST' */
1821
paul94f2b392005-06-28 12:44:16 +00001822static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001823route_match_ipv6_address (void *rule, struct prefix *prefix,
1824 route_map_object_t type, void *object)
1825{
1826 struct access_list *alist;
1827
1828 if (type == RMAP_BGP)
1829 {
1830 alist = access_list_lookup (AFI_IP6, (char *) rule);
1831 if (alist == NULL)
1832 return RMAP_NOMATCH;
1833
1834 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1835 RMAP_NOMATCH : RMAP_MATCH);
1836 }
1837 return RMAP_NOMATCH;
1838}
1839
paul94f2b392005-06-28 12:44:16 +00001840static void *
paulfd79ac92004-10-13 05:06:08 +00001841route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001842{
1843 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1844}
1845
paul94f2b392005-06-28 12:44:16 +00001846static void
paul718e3742002-12-13 20:15:29 +00001847route_match_ipv6_address_free (void *rule)
1848{
1849 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1850}
1851
1852/* Route map commands for ip address matching. */
1853struct route_map_rule_cmd route_match_ipv6_address_cmd =
1854{
1855 "ipv6 address",
1856 route_match_ipv6_address,
1857 route_match_ipv6_address_compile,
1858 route_match_ipv6_address_free
1859};
1860
1861/* `match ipv6 next-hop IP_ADDRESS' */
1862
paul94f2b392005-06-28 12:44:16 +00001863static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001864route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1865 route_map_object_t type, void *object)
1866{
1867 struct in6_addr *addr;
1868 struct bgp_info *bgp_info;
1869
1870 if (type == RMAP_BGP)
1871 {
1872 addr = rule;
1873 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001874
1875 if (!bgp_info->attr->extra)
1876 return RMAP_NOMATCH;
1877
1878 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001879 return RMAP_MATCH;
1880
Paul Jakmafb982c22007-05-04 20:15:47 +00001881 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1882 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001883 return RMAP_MATCH;
1884
1885 return RMAP_NOMATCH;
1886 }
1887
1888 return RMAP_NOMATCH;
1889}
1890
paul94f2b392005-06-28 12:44:16 +00001891static void *
paulfd79ac92004-10-13 05:06:08 +00001892route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001893{
1894 struct in6_addr *address;
1895 int ret;
1896
1897 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1898
1899 ret = inet_pton (AF_INET6, arg, address);
1900 if (!ret)
1901 {
1902 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1903 return NULL;
1904 }
1905
1906 return address;
1907}
1908
paul94f2b392005-06-28 12:44:16 +00001909static void
paul718e3742002-12-13 20:15:29 +00001910route_match_ipv6_next_hop_free (void *rule)
1911{
1912 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1913}
1914
1915struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1916{
1917 "ipv6 next-hop",
1918 route_match_ipv6_next_hop,
1919 route_match_ipv6_next_hop_compile,
1920 route_match_ipv6_next_hop_free
1921};
1922
1923/* `match ipv6 address prefix-list PREFIX_LIST' */
1924
paul94f2b392005-06-28 12:44:16 +00001925static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001926route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1927 route_map_object_t type, void *object)
1928{
1929 struct prefix_list *plist;
1930
1931 if (type == RMAP_BGP)
1932 {
1933 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1934 if (plist == NULL)
1935 return RMAP_NOMATCH;
1936
1937 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1938 RMAP_NOMATCH : RMAP_MATCH);
1939 }
1940 return RMAP_NOMATCH;
1941}
1942
paul94f2b392005-06-28 12:44:16 +00001943static void *
paulfd79ac92004-10-13 05:06:08 +00001944route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001945{
1946 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1947}
1948
paul94f2b392005-06-28 12:44:16 +00001949static void
paul718e3742002-12-13 20:15:29 +00001950route_match_ipv6_address_prefix_list_free (void *rule)
1951{
1952 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1953}
1954
1955struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1956{
1957 "ipv6 address prefix-list",
1958 route_match_ipv6_address_prefix_list,
1959 route_match_ipv6_address_prefix_list_compile,
1960 route_match_ipv6_address_prefix_list_free
1961};
1962
1963/* `set ipv6 nexthop global IP_ADDRESS' */
1964
1965/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001966static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001967route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1968 route_map_object_t type, void *object)
1969{
1970 struct in6_addr *address;
1971 struct bgp_info *bgp_info;
1972
1973 if (type == RMAP_BGP)
1974 {
1975 /* Fetch routemap's rule information. */
1976 address = rule;
1977 bgp_info = object;
1978
1979 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001980 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001981
1982 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001983 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1984 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001985 }
1986
1987 return RMAP_OKAY;
1988}
1989
1990/* Route map `ip next-hop' compile function. Given string is converted
1991 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001992static void *
paulfd79ac92004-10-13 05:06:08 +00001993route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001994{
1995 int ret;
1996 struct in6_addr *address;
1997
1998 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1999
2000 ret = inet_pton (AF_INET6, arg, address);
2001
2002 if (ret == 0)
2003 {
2004 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2005 return NULL;
2006 }
2007
2008 return address;
2009}
2010
2011/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002012static void
paul718e3742002-12-13 20:15:29 +00002013route_set_ipv6_nexthop_global_free (void *rule)
2014{
2015 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2016}
2017
2018/* Route map commands for ip nexthop set. */
2019struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2020{
2021 "ipv6 next-hop global",
2022 route_set_ipv6_nexthop_global,
2023 route_set_ipv6_nexthop_global_compile,
2024 route_set_ipv6_nexthop_global_free
2025};
2026
2027/* `set ipv6 nexthop local IP_ADDRESS' */
2028
2029/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002030static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002031route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2032 route_map_object_t type, void *object)
2033{
2034 struct in6_addr *address;
2035 struct bgp_info *bgp_info;
2036
2037 if (type == RMAP_BGP)
2038 {
2039 /* Fetch routemap's rule information. */
2040 address = rule;
2041 bgp_info = object;
2042
2043 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002044 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002045
2046 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002047 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2048 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002049 }
2050
2051 return RMAP_OKAY;
2052}
2053
2054/* Route map `ip nexthop' compile function. Given string is converted
2055 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002056static void *
paulfd79ac92004-10-13 05:06:08 +00002057route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002058{
2059 int ret;
2060 struct in6_addr *address;
2061
2062 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2063
2064 ret = inet_pton (AF_INET6, arg, address);
2065
2066 if (ret == 0)
2067 {
2068 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2069 return NULL;
2070 }
2071
2072 return address;
2073}
2074
2075/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002076static void
paul718e3742002-12-13 20:15:29 +00002077route_set_ipv6_nexthop_local_free (void *rule)
2078{
2079 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2080}
2081
2082/* Route map commands for ip nexthop set. */
2083struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2084{
2085 "ipv6 next-hop local",
2086 route_set_ipv6_nexthop_local,
2087 route_set_ipv6_nexthop_local_compile,
2088 route_set_ipv6_nexthop_local_free
2089};
2090#endif /* HAVE_IPV6 */
2091
2092/* `set vpnv4 nexthop A.B.C.D' */
2093
paul94f2b392005-06-28 12:44:16 +00002094static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002095route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2096 route_map_object_t type, void *object)
2097{
2098 struct in_addr *address;
2099 struct bgp_info *bgp_info;
2100
2101 if (type == RMAP_BGP)
2102 {
2103 /* Fetch routemap's rule information. */
2104 address = rule;
2105 bgp_info = object;
2106
2107 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002108 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002109 }
2110
2111 return RMAP_OKAY;
2112}
2113
paul94f2b392005-06-28 12:44:16 +00002114static void *
paulfd79ac92004-10-13 05:06:08 +00002115route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002116{
2117 int ret;
2118 struct in_addr *address;
2119
2120 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2121
2122 ret = inet_aton (arg, address);
2123
2124 if (ret == 0)
2125 {
2126 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2127 return NULL;
2128 }
2129
2130 return address;
2131}
2132
paul94f2b392005-06-28 12:44:16 +00002133static void
paul718e3742002-12-13 20:15:29 +00002134route_set_vpnv4_nexthop_free (void *rule)
2135{
2136 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2137}
2138
2139/* Route map commands for ip nexthop set. */
2140struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2141{
2142 "vpnv4 next-hop",
2143 route_set_vpnv4_nexthop,
2144 route_set_vpnv4_nexthop_compile,
2145 route_set_vpnv4_nexthop_free
2146};
2147
2148/* `set originator-id' */
2149
2150/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002151static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002152route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2153{
2154 struct in_addr *address;
2155 struct bgp_info *bgp_info;
2156
2157 if (type == RMAP_BGP)
2158 {
2159 address = rule;
2160 bgp_info = object;
2161
2162 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002163 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002164 }
2165
2166 return RMAP_OKAY;
2167}
2168
2169/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002170static void *
paulfd79ac92004-10-13 05:06:08 +00002171route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002172{
2173 int ret;
2174 struct in_addr *address;
2175
2176 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2177
2178 ret = inet_aton (arg, address);
2179
2180 if (ret == 0)
2181 {
2182 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2183 return NULL;
2184 }
2185
2186 return address;
2187}
2188
2189/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002190static void
paul718e3742002-12-13 20:15:29 +00002191route_set_originator_id_free (void *rule)
2192{
2193 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2194}
2195
2196/* Set metric rule structure. */
2197struct route_map_rule_cmd route_set_originator_id_cmd =
2198{
2199 "originator-id",
2200 route_set_originator_id,
2201 route_set_originator_id_compile,
2202 route_set_originator_id_free,
2203};
2204
2205/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002206static int
paul718e3742002-12-13 20:15:29 +00002207bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002208 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002209{
2210 int ret;
2211
2212 ret = route_map_add_match (index, command, arg);
2213 if (ret)
2214 {
2215 switch (ret)
2216 {
2217 case RMAP_RULE_MISSING:
2218 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2219 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002220 case RMAP_COMPILE_ERROR:
2221 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2222 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002223 }
2224 }
2225 return CMD_SUCCESS;
2226}
2227
2228/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002229static int
paul718e3742002-12-13 20:15:29 +00002230bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002231 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002232{
2233 int ret;
2234
2235 ret = route_map_delete_match (index, command, arg);
2236 if (ret)
2237 {
2238 switch (ret)
2239 {
2240 case RMAP_RULE_MISSING:
2241 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2242 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002243 case RMAP_COMPILE_ERROR:
2244 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2245 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002246 }
2247 }
2248 return CMD_SUCCESS;
2249}
2250
2251/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002252static int
paul718e3742002-12-13 20:15:29 +00002253bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002254 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002255{
2256 int ret;
2257
2258 ret = route_map_add_set (index, command, arg);
2259 if (ret)
2260 {
2261 switch (ret)
2262 {
2263 case RMAP_RULE_MISSING:
2264 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2265 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002266 case RMAP_COMPILE_ERROR:
2267 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2268 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002269 }
2270 }
2271 return CMD_SUCCESS;
2272}
2273
2274/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002275static int
paul718e3742002-12-13 20:15:29 +00002276bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002277 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002278{
2279 int ret;
2280
2281 ret = route_map_delete_set (index, command, arg);
2282 if (ret)
2283 {
2284 switch (ret)
2285 {
2286 case RMAP_RULE_MISSING:
2287 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2288 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002289 case RMAP_COMPILE_ERROR:
2290 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2291 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002292 }
2293 }
2294 return CMD_SUCCESS;
2295}
2296
2297/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002298static void
paulfd79ac92004-10-13 05:06:08 +00002299bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002300{
2301 int i;
2302 afi_t afi;
2303 safi_t safi;
2304 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002305 struct listnode *node, *nnode;
2306 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002307 struct bgp *bgp;
2308 struct peer *peer;
2309 struct peer_group *group;
2310 struct bgp_filter *filter;
2311 struct bgp_node *bn;
2312 struct bgp_static *bgp_static;
2313
2314 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002315 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002316 {
paul1eb8ef22005-04-07 07:30:20 +00002317 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002318 {
2319 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2320 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2321 {
2322 filter = &peer->filter[afi][safi];
2323
paulfee0f4c2004-09-13 05:12:46 +00002324 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002325 {
2326 if (filter->map[direct].name)
2327 filter->map[direct].map =
2328 route_map_lookup_by_name (filter->map[direct].name);
2329 else
2330 filter->map[direct].map = NULL;
2331 }
2332
2333 if (filter->usmap.name)
2334 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2335 else
2336 filter->usmap.map = NULL;
2337 }
2338 }
paul1eb8ef22005-04-07 07:30:20 +00002339 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002340 {
2341 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2342 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2343 {
2344 filter = &group->conf->filter[afi][safi];
2345
paulfee0f4c2004-09-13 05:12:46 +00002346 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002347 {
2348 if (filter->map[direct].name)
2349 filter->map[direct].map =
2350 route_map_lookup_by_name (filter->map[direct].name);
2351 else
2352 filter->map[direct].map = NULL;
2353 }
2354
2355 if (filter->usmap.name)
2356 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2357 else
2358 filter->usmap.map = NULL;
2359 }
2360 }
2361 }
2362
2363 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002364 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002365 {
paul1eb8ef22005-04-07 07:30:20 +00002366 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002367 {
2368 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2369 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2370 {
2371 if (peer->default_rmap[afi][safi].name)
2372 peer->default_rmap[afi][safi].map =
2373 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2374 else
2375 peer->default_rmap[afi][safi].map = NULL;
2376 }
2377 }
2378 }
2379
2380 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002381 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002382 {
2383 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2384 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2385 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2386 bn = bgp_route_next (bn))
2387 if ((bgp_static = bn->info) != NULL)
2388 {
2389 if (bgp_static->rmap.name)
2390 bgp_static->rmap.map =
2391 route_map_lookup_by_name (bgp_static->rmap.name);
2392 else
2393 bgp_static->rmap.map = NULL;
2394 }
2395 }
2396
2397 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002398 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002399 {
2400 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2401 {
2402 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2403 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2404 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2405#ifdef HAVE_IPV6
2406 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2407 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2408 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2409#endif /* HAVE_IPV6 */
2410 }
2411 }
2412}
2413
paulfee0f4c2004-09-13 05:12:46 +00002414DEFUN (match_peer,
2415 match_peer_cmd,
2416 "match peer (A.B.C.D|X:X::X:X)",
2417 MATCH_STR
2418 "Match peer address\n"
2419 "IPv6 address of peer\n"
2420 "IP address of peer\n")
2421{
2422 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2423}
2424
2425DEFUN (match_peer_local,
2426 match_peer_local_cmd,
2427 "match peer local",
2428 MATCH_STR
2429 "Match peer address\n"
2430 "Static or Redistributed routes\n")
2431{
2432 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2433}
2434
2435DEFUN (no_match_peer,
2436 no_match_peer_cmd,
2437 "no match peer",
2438 NO_STR
2439 MATCH_STR
2440 "Match peer address\n")
2441{
2442 if (argc == 0)
2443 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2444
2445 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2446}
2447
2448ALIAS (no_match_peer,
2449 no_match_peer_val_cmd,
2450 "no match peer (A.B.C.D|X:X::X:X)",
2451 NO_STR
2452 MATCH_STR
2453 "Match peer address\n"
2454 "IPv6 address of peer\n"
2455 "IP address of peer\n")
2456
2457ALIAS (no_match_peer,
2458 no_match_peer_local_cmd,
2459 "no match peer local",
2460 NO_STR
2461 MATCH_STR
2462 "Match peer address\n"
2463 "Static or Redistributed routes\n")
2464
paul718e3742002-12-13 20:15:29 +00002465DEFUN (match_ip_address,
2466 match_ip_address_cmd,
2467 "match ip address (<1-199>|<1300-2699>|WORD)",
2468 MATCH_STR
2469 IP_STR
2470 "Match address of route\n"
2471 "IP access-list number\n"
2472 "IP access-list number (expanded range)\n"
2473 "IP Access-list name\n")
2474{
2475 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2476}
2477
2478DEFUN (no_match_ip_address,
2479 no_match_ip_address_cmd,
2480 "no match ip address",
2481 NO_STR
2482 MATCH_STR
2483 IP_STR
2484 "Match address of route\n")
2485{
2486 if (argc == 0)
2487 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2488
2489 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2490}
2491
2492ALIAS (no_match_ip_address,
2493 no_match_ip_address_val_cmd,
2494 "no match ip address (<1-199>|<1300-2699>|WORD)",
2495 NO_STR
2496 MATCH_STR
2497 IP_STR
2498 "Match address of route\n"
2499 "IP access-list number\n"
2500 "IP access-list number (expanded range)\n"
2501 "IP Access-list name\n")
2502
2503DEFUN (match_ip_next_hop,
2504 match_ip_next_hop_cmd,
2505 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2506 MATCH_STR
2507 IP_STR
2508 "Match next-hop address of route\n"
2509 "IP access-list number\n"
2510 "IP access-list number (expanded range)\n"
2511 "IP Access-list name\n")
2512{
2513 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2514}
2515
2516DEFUN (no_match_ip_next_hop,
2517 no_match_ip_next_hop_cmd,
2518 "no match ip next-hop",
2519 NO_STR
2520 MATCH_STR
2521 IP_STR
2522 "Match next-hop address of route\n")
2523{
2524 if (argc == 0)
2525 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2526
2527 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2528}
2529
2530ALIAS (no_match_ip_next_hop,
2531 no_match_ip_next_hop_val_cmd,
2532 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2533 NO_STR
2534 MATCH_STR
2535 IP_STR
2536 "Match next-hop address of route\n"
2537 "IP access-list number\n"
2538 "IP access-list number (expanded range)\n"
2539 "IP Access-list name\n")
2540
hassoc1643bb2005-02-02 16:43:17 +00002541DEFUN (match_ip_route_source,
2542 match_ip_route_source_cmd,
2543 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2544 MATCH_STR
2545 IP_STR
2546 "Match advertising source address of route\n"
2547 "IP access-list number\n"
2548 "IP access-list number (expanded range)\n"
2549 "IP standard access-list name\n")
2550{
2551 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2552}
2553
2554DEFUN (no_match_ip_route_source,
2555 no_match_ip_route_source_cmd,
2556 "no match ip route-source",
2557 NO_STR
2558 MATCH_STR
2559 IP_STR
2560 "Match advertising source address of route\n")
2561{
2562 if (argc == 0)
2563 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2564
2565 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2566}
2567
2568ALIAS (no_match_ip_route_source,
2569 no_match_ip_route_source_val_cmd,
2570 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2571 NO_STR
2572 MATCH_STR
2573 IP_STR
2574 "Match advertising source address of route\n"
2575 "IP access-list number\n"
2576 "IP access-list number (expanded range)\n"
2577 "IP standard access-list name\n");
2578
paul718e3742002-12-13 20:15:29 +00002579DEFUN (match_ip_address_prefix_list,
2580 match_ip_address_prefix_list_cmd,
2581 "match ip address prefix-list WORD",
2582 MATCH_STR
2583 IP_STR
2584 "Match address of route\n"
2585 "Match entries of prefix-lists\n"
2586 "IP prefix-list name\n")
2587{
2588 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2589}
2590
2591DEFUN (no_match_ip_address_prefix_list,
2592 no_match_ip_address_prefix_list_cmd,
2593 "no match ip address prefix-list",
2594 NO_STR
2595 MATCH_STR
2596 IP_STR
2597 "Match address of route\n"
2598 "Match entries of prefix-lists\n")
2599{
2600 if (argc == 0)
2601 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2602
2603 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2604}
2605
2606ALIAS (no_match_ip_address_prefix_list,
2607 no_match_ip_address_prefix_list_val_cmd,
2608 "no match ip address prefix-list WORD",
2609 NO_STR
2610 MATCH_STR
2611 IP_STR
2612 "Match address of route\n"
2613 "Match entries of prefix-lists\n"
2614 "IP prefix-list name\n")
2615
2616DEFUN (match_ip_next_hop_prefix_list,
2617 match_ip_next_hop_prefix_list_cmd,
2618 "match ip next-hop prefix-list WORD",
2619 MATCH_STR
2620 IP_STR
2621 "Match next-hop address of route\n"
2622 "Match entries of prefix-lists\n"
2623 "IP prefix-list name\n")
2624{
2625 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2626}
2627
2628DEFUN (no_match_ip_next_hop_prefix_list,
2629 no_match_ip_next_hop_prefix_list_cmd,
2630 "no match ip next-hop prefix-list",
2631 NO_STR
2632 MATCH_STR
2633 IP_STR
2634 "Match next-hop address of route\n"
2635 "Match entries of prefix-lists\n")
2636{
2637 if (argc == 0)
2638 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2639
2640 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2641}
2642
2643ALIAS (no_match_ip_next_hop_prefix_list,
2644 no_match_ip_next_hop_prefix_list_val_cmd,
2645 "no match ip next-hop prefix-list WORD",
2646 NO_STR
2647 MATCH_STR
2648 IP_STR
2649 "Match next-hop address of route\n"
2650 "Match entries of prefix-lists\n"
2651 "IP prefix-list name\n")
2652
hassoc1643bb2005-02-02 16:43:17 +00002653DEFUN (match_ip_route_source_prefix_list,
2654 match_ip_route_source_prefix_list_cmd,
2655 "match ip route-source prefix-list WORD",
2656 MATCH_STR
2657 IP_STR
2658 "Match advertising source address of route\n"
2659 "Match entries of prefix-lists\n"
2660 "IP prefix-list name\n")
2661{
2662 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2663}
2664
2665DEFUN (no_match_ip_route_source_prefix_list,
2666 no_match_ip_route_source_prefix_list_cmd,
2667 "no match ip route-source prefix-list",
2668 NO_STR
2669 MATCH_STR
2670 IP_STR
2671 "Match advertising source address of route\n"
2672 "Match entries of prefix-lists\n")
2673{
2674 if (argc == 0)
2675 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2676
2677 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2678}
2679
2680ALIAS (no_match_ip_route_source_prefix_list,
2681 no_match_ip_route_source_prefix_list_val_cmd,
2682 "no match ip route-source prefix-list WORD",
2683 NO_STR
2684 MATCH_STR
2685 IP_STR
2686 "Match advertising source address of route\n"
2687 "Match entries of prefix-lists\n"
2688 "IP prefix-list name\n");
2689
paul718e3742002-12-13 20:15:29 +00002690DEFUN (match_metric,
2691 match_metric_cmd,
2692 "match metric <0-4294967295>",
2693 MATCH_STR
2694 "Match metric of route\n"
2695 "Metric value\n")
2696{
2697 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2698}
2699
2700DEFUN (no_match_metric,
2701 no_match_metric_cmd,
2702 "no match metric",
2703 NO_STR
2704 MATCH_STR
2705 "Match metric of route\n")
2706{
2707 if (argc == 0)
2708 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2709
2710 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2711}
2712
2713ALIAS (no_match_metric,
2714 no_match_metric_val_cmd,
2715 "no match metric <0-4294967295>",
2716 NO_STR
2717 MATCH_STR
2718 "Match metric of route\n"
2719 "Metric value\n")
2720
2721DEFUN (match_community,
2722 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002723 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002724 MATCH_STR
2725 "Match BGP community list\n"
2726 "Community-list number (standard)\n"
2727 "Community-list number (expanded)\n"
2728 "Community-list name\n")
2729{
2730 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2731}
2732
2733DEFUN (match_community_exact,
2734 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002735 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002736 MATCH_STR
2737 "Match BGP community list\n"
2738 "Community-list number (standard)\n"
2739 "Community-list number (expanded)\n"
2740 "Community-list name\n"
2741 "Do exact matching of communities\n")
2742{
2743 int ret;
2744 char *argstr;
2745
2746 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2747 strlen (argv[0]) + strlen ("exact-match") + 2);
2748
2749 sprintf (argstr, "%s exact-match", argv[0]);
2750
2751 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2752
2753 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2754
2755 return ret;
2756}
2757
2758DEFUN (no_match_community,
2759 no_match_community_cmd,
2760 "no match community",
2761 NO_STR
2762 MATCH_STR
2763 "Match BGP community list\n")
2764{
2765 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2766}
2767
2768ALIAS (no_match_community,
2769 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002770 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002771 NO_STR
2772 MATCH_STR
2773 "Match BGP community list\n"
2774 "Community-list number (standard)\n"
2775 "Community-list number (expanded)\n"
2776 "Community-list name\n")
2777
2778ALIAS (no_match_community,
2779 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002780 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002781 NO_STR
2782 MATCH_STR
2783 "Match BGP community list\n"
2784 "Community-list number (standard)\n"
2785 "Community-list number (expanded)\n"
2786 "Community-list name\n"
2787 "Do exact matching of communities\n")
2788
paul73ffb252003-04-19 15:49:49 +00002789DEFUN (match_ecommunity,
2790 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002791 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002792 MATCH_STR
2793 "Match BGP/VPN extended community list\n"
2794 "Extended community-list number (standard)\n"
2795 "Extended community-list number (expanded)\n"
2796 "Extended community-list name\n")
2797{
2798 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2799}
2800
2801DEFUN (no_match_ecommunity,
2802 no_match_ecommunity_cmd,
2803 "no match extcommunity",
2804 NO_STR
2805 MATCH_STR
2806 "Match BGP/VPN extended community list\n")
2807{
2808 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2809}
2810
2811ALIAS (no_match_ecommunity,
2812 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002813 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002814 NO_STR
2815 MATCH_STR
2816 "Match BGP/VPN extended community list\n"
2817 "Extended community-list number (standard)\n"
2818 "Extended community-list number (expanded)\n"
2819 "Extended community-list name\n")
2820
paul718e3742002-12-13 20:15:29 +00002821DEFUN (match_aspath,
2822 match_aspath_cmd,
2823 "match as-path WORD",
2824 MATCH_STR
2825 "Match BGP AS path list\n"
2826 "AS path access-list name\n")
2827{
2828 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2829}
2830
2831DEFUN (no_match_aspath,
2832 no_match_aspath_cmd,
2833 "no match as-path",
2834 NO_STR
2835 MATCH_STR
2836 "Match BGP AS path list\n")
2837{
2838 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2839}
2840
2841ALIAS (no_match_aspath,
2842 no_match_aspath_val_cmd,
2843 "no match as-path WORD",
2844 NO_STR
2845 MATCH_STR
2846 "Match BGP AS path list\n"
2847 "AS path access-list name\n")
2848
2849DEFUN (match_origin,
2850 match_origin_cmd,
2851 "match origin (egp|igp|incomplete)",
2852 MATCH_STR
2853 "BGP origin code\n"
2854 "remote EGP\n"
2855 "local IGP\n"
2856 "unknown heritage\n")
2857{
2858 if (strncmp (argv[0], "igp", 2) == 0)
2859 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2860 if (strncmp (argv[0], "egp", 1) == 0)
2861 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2862 if (strncmp (argv[0], "incomplete", 2) == 0)
2863 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2864
2865 return CMD_WARNING;
2866}
2867
2868DEFUN (no_match_origin,
2869 no_match_origin_cmd,
2870 "no match origin",
2871 NO_STR
2872 MATCH_STR
2873 "BGP origin code\n")
2874{
2875 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2876}
2877
2878ALIAS (no_match_origin,
2879 no_match_origin_val_cmd,
2880 "no match origin (egp|igp|incomplete)",
2881 NO_STR
2882 MATCH_STR
2883 "BGP origin code\n"
2884 "remote EGP\n"
2885 "local IGP\n"
2886 "unknown heritage\n")
2887
2888DEFUN (set_ip_nexthop,
2889 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002890 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002891 SET_STR
2892 IP_STR
2893 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002894 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002895{
2896 union sockunion su;
2897 int ret;
2898
2899 ret = str2sockunion (argv[0], &su);
2900 if (ret < 0)
2901 {
2902 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2903 return CMD_WARNING;
2904 }
2905
2906 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2907}
2908
paulaf5cd0a2003-11-02 07:24:40 +00002909DEFUN (set_ip_nexthop_peer,
2910 set_ip_nexthop_peer_cmd,
2911 "set ip next-hop peer-address",
2912 SET_STR
2913 IP_STR
2914 "Next hop address\n"
2915 "Use peer address (for BGP only)\n")
2916{
2917 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2918}
2919
paul94f2b392005-06-28 12:44:16 +00002920DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002921 no_set_ip_nexthop_peer_cmd,
2922 "no set ip next-hop peer-address",
2923 NO_STR
2924 SET_STR
2925 IP_STR
2926 "Next hop address\n"
2927 "Use peer address (for BGP only)\n")
2928{
2929 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2930}
2931
2932
paul718e3742002-12-13 20:15:29 +00002933DEFUN (no_set_ip_nexthop,
2934 no_set_ip_nexthop_cmd,
2935 "no set ip next-hop",
2936 NO_STR
2937 SET_STR
paul718e3742002-12-13 20:15:29 +00002938 "Next hop address\n")
2939{
paulaf5cd0a2003-11-02 07:24:40 +00002940 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002941 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2942
2943 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2944}
2945
2946ALIAS (no_set_ip_nexthop,
2947 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002948 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002949 NO_STR
2950 SET_STR
2951 IP_STR
2952 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002953 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002954
2955DEFUN (set_metric,
2956 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002957 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002958 SET_STR
2959 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002960 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002961{
2962 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2963}
2964
paul73ffb252003-04-19 15:49:49 +00002965ALIAS (set_metric,
2966 set_metric_addsub_cmd,
2967 "set metric <+/-metric>",
2968 SET_STR
2969 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002970 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002971
paul718e3742002-12-13 20:15:29 +00002972DEFUN (no_set_metric,
2973 no_set_metric_cmd,
2974 "no set metric",
2975 NO_STR
2976 SET_STR
2977 "Metric value for destination routing protocol\n")
2978{
2979 if (argc == 0)
2980 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2981
2982 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2983}
2984
2985ALIAS (no_set_metric,
2986 no_set_metric_val_cmd,
2987 "no set metric <0-4294967295>",
2988 NO_STR
2989 SET_STR
2990 "Metric value for destination routing protocol\n"
2991 "Metric value\n")
2992
2993DEFUN (set_local_pref,
2994 set_local_pref_cmd,
2995 "set local-preference <0-4294967295>",
2996 SET_STR
2997 "BGP local preference path attribute\n"
2998 "Preference value\n")
2999{
3000 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3001}
3002
3003DEFUN (no_set_local_pref,
3004 no_set_local_pref_cmd,
3005 "no set local-preference",
3006 NO_STR
3007 SET_STR
3008 "BGP local preference path attribute\n")
3009{
3010 if (argc == 0)
3011 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3012
3013 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3014}
3015
3016ALIAS (no_set_local_pref,
3017 no_set_local_pref_val_cmd,
3018 "no set local-preference <0-4294967295>",
3019 NO_STR
3020 SET_STR
3021 "BGP local preference path attribute\n"
3022 "Preference value\n")
3023
3024DEFUN (set_weight,
3025 set_weight_cmd,
3026 "set weight <0-4294967295>",
3027 SET_STR
3028 "BGP weight for routing table\n"
3029 "Weight value\n")
3030{
3031 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3032}
3033
3034DEFUN (no_set_weight,
3035 no_set_weight_cmd,
3036 "no set weight",
3037 NO_STR
3038 SET_STR
3039 "BGP weight for routing table\n")
3040{
3041 if (argc == 0)
3042 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3043
3044 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3045}
3046
3047ALIAS (no_set_weight,
3048 no_set_weight_val_cmd,
3049 "no set weight <0-4294967295>",
3050 NO_STR
3051 SET_STR
3052 "BGP weight for routing table\n"
3053 "Weight value\n")
3054
3055DEFUN (set_aspath_prepend,
3056 set_aspath_prepend_cmd,
3057 "set as-path prepend .<1-65535>",
3058 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003059 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003060 "Prepend to the as-path\n"
3061 "AS number\n")
3062{
3063 int ret;
3064 char *str;
3065
3066 str = argv_concat (argv, argc, 0);
3067 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3068 XFREE (MTYPE_TMP, str);
3069
3070 return ret;
3071}
3072
3073DEFUN (no_set_aspath_prepend,
3074 no_set_aspath_prepend_cmd,
3075 "no set as-path prepend",
3076 NO_STR
3077 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003078 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003079 "Prepend to the as-path\n")
3080{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003081 int ret;
3082 char *str;
3083
3084 if (argc == 0)
3085 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3086
3087 str = argv_concat (argv, argc, 0);
3088 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3089 XFREE (MTYPE_TMP, str);
3090 return ret;
paul718e3742002-12-13 20:15:29 +00003091}
3092
3093ALIAS (no_set_aspath_prepend,
3094 no_set_aspath_prepend_val_cmd,
3095 "no set as-path prepend .<1-65535>",
3096 NO_STR
3097 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003098 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003099 "Prepend to the as-path\n"
3100 "AS number\n")
3101
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003102DEFUN (set_aspath_exclude,
3103 set_aspath_exclude_cmd,
3104 "set as-path exclude .<1-65535>",
3105 SET_STR
3106 "Transform BGP AS-path attribute\n"
3107 "Exclude from the as-path\n"
3108 "AS number\n")
3109{
3110 int ret;
3111 char *str;
3112
3113 str = argv_concat (argv, argc, 0);
3114 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3115 XFREE (MTYPE_TMP, str);
3116 return ret;
3117}
3118
3119DEFUN (no_set_aspath_exclude,
3120 no_set_aspath_exclude_cmd,
3121 "no set as-path exclude",
3122 NO_STR
3123 SET_STR
3124 "Transform BGP AS_PATH attribute\n"
3125 "Exclude from the as-path\n")
3126{
3127 int ret;
3128 char *str;
3129
3130 if (argc == 0)
3131 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3132
3133 str = argv_concat (argv, argc, 0);
3134 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3135 XFREE (MTYPE_TMP, str);
3136 return ret;
3137}
3138
3139ALIAS (no_set_aspath_exclude,
3140 no_set_aspath_exclude_val_cmd,
3141 "no set as-path exclude .<1-65535>",
3142 NO_STR
3143 SET_STR
3144 "Transform BGP AS_PATH attribute\n"
3145 "Exclude from the as-path\n"
3146 "AS number\n")
3147
paul718e3742002-12-13 20:15:29 +00003148DEFUN (set_community,
3149 set_community_cmd,
3150 "set community .AA:NN",
3151 SET_STR
3152 "BGP community attribute\n"
3153 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3154{
3155 int i;
3156 int first = 0;
3157 int additive = 0;
3158 struct buffer *b;
3159 struct community *com = NULL;
3160 char *str;
3161 char *argstr;
3162 int ret;
3163
3164 b = buffer_new (1024);
3165
3166 for (i = 0; i < argc; i++)
3167 {
3168 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3169 {
3170 additive = 1;
3171 continue;
3172 }
3173
3174 if (first)
3175 buffer_putc (b, ' ');
3176 else
3177 first = 1;
3178
3179 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3180 {
3181 buffer_putstr (b, "internet");
3182 continue;
3183 }
3184 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3185 {
3186 buffer_putstr (b, "local-AS");
3187 continue;
3188 }
3189 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3190 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3191 {
3192 buffer_putstr (b, "no-advertise");
3193 continue;
3194 }
3195 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3196 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3197 {
3198 buffer_putstr (b, "no-export");
3199 continue;
3200 }
3201 buffer_putstr (b, argv[i]);
3202 }
3203 buffer_putc (b, '\0');
3204
3205 /* Fetch result string then compile it to communities attribute. */
3206 str = buffer_getstr (b);
3207 buffer_free (b);
3208
3209 if (str)
3210 {
3211 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003212 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003213 }
3214
3215 /* Can't compile user input into communities attribute. */
3216 if (! com)
3217 {
3218 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3219 return CMD_WARNING;
3220 }
3221
3222 /* Set communites attribute string. */
3223 str = community_str (com);
3224
3225 if (additive)
3226 {
3227 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3228 strcpy (argstr, str);
3229 strcpy (argstr + strlen (str), " additive");
3230 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3231 XFREE (MTYPE_TMP, argstr);
3232 }
3233 else
3234 ret = bgp_route_set_add (vty, vty->index, "community", str);
3235
3236 community_free (com);
3237
3238 return ret;
3239}
3240
3241DEFUN (set_community_none,
3242 set_community_none_cmd,
3243 "set community none",
3244 SET_STR
3245 "BGP community attribute\n"
3246 "No community attribute\n")
3247{
3248 return bgp_route_set_add (vty, vty->index, "community", "none");
3249}
3250
3251DEFUN (no_set_community,
3252 no_set_community_cmd,
3253 "no set community",
3254 NO_STR
3255 SET_STR
3256 "BGP community attribute\n")
3257{
3258 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3259}
3260
3261ALIAS (no_set_community,
3262 no_set_community_val_cmd,
3263 "no set community .AA:NN",
3264 NO_STR
3265 SET_STR
3266 "BGP community attribute\n"
3267 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3268
3269ALIAS (no_set_community,
3270 no_set_community_none_cmd,
3271 "no set community none",
3272 NO_STR
3273 SET_STR
3274 "BGP community attribute\n"
3275 "No community attribute\n")
3276
3277DEFUN (set_community_delete,
3278 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003279 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003280 SET_STR
3281 "set BGP community list (for deletion)\n"
3282 "Community-list number (standard)\n"
3283 "Communitly-list number (expanded)\n"
3284 "Community-list name\n"
3285 "Delete matching communities\n")
3286{
3287 char *str;
3288
3289 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3290 strcpy (str, argv[0]);
3291 strcpy (str + strlen (argv[0]), " delete");
3292
3293 bgp_route_set_add (vty, vty->index, "comm-list", str);
3294
3295 XFREE (MTYPE_TMP, str);
3296 return CMD_SUCCESS;
3297}
3298
3299DEFUN (no_set_community_delete,
3300 no_set_community_delete_cmd,
3301 "no set comm-list",
3302 NO_STR
3303 SET_STR
3304 "set BGP community list (for deletion)\n")
3305{
3306 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3307}
3308
3309ALIAS (no_set_community_delete,
3310 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003311 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003312 NO_STR
3313 SET_STR
3314 "set BGP community list (for deletion)\n"
3315 "Community-list number (standard)\n"
3316 "Communitly-list number (expanded)\n"
3317 "Community-list name\n"
3318 "Delete matching communities\n")
3319
3320DEFUN (set_ecommunity_rt,
3321 set_ecommunity_rt_cmd,
3322 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3323 SET_STR
3324 "BGP extended community attribute\n"
3325 "Route Target extened communityt\n"
3326 "VPN extended community\n")
3327{
3328 int ret;
3329 char *str;
3330
3331 str = argv_concat (argv, argc, 0);
3332 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3333 XFREE (MTYPE_TMP, str);
3334
3335 return ret;
3336}
3337
3338DEFUN (no_set_ecommunity_rt,
3339 no_set_ecommunity_rt_cmd,
3340 "no set extcommunity rt",
3341 NO_STR
3342 SET_STR
3343 "BGP extended community attribute\n"
3344 "Route Target extened communityt\n")
3345{
3346 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3347}
3348
3349ALIAS (no_set_ecommunity_rt,
3350 no_set_ecommunity_rt_val_cmd,
3351 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3352 NO_STR
3353 SET_STR
3354 "BGP extended community attribute\n"
3355 "Route Target extened communityt\n"
3356 "VPN extended community\n")
3357
3358DEFUN (set_ecommunity_soo,
3359 set_ecommunity_soo_cmd,
3360 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3361 SET_STR
3362 "BGP extended community attribute\n"
3363 "Site-of-Origin extended community\n"
3364 "VPN extended community\n")
3365{
3366 int ret;
3367 char *str;
3368
3369 str = argv_concat (argv, argc, 0);
3370 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3371 XFREE (MTYPE_TMP, str);
3372 return ret;
3373}
3374
3375DEFUN (no_set_ecommunity_soo,
3376 no_set_ecommunity_soo_cmd,
3377 "no set extcommunity soo",
3378 NO_STR
3379 SET_STR
3380 "BGP extended community attribute\n"
3381 "Site-of-Origin extended community\n")
3382{
3383 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3384}
3385
3386ALIAS (no_set_ecommunity_soo,
3387 no_set_ecommunity_soo_val_cmd,
3388 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3389 NO_STR
3390 SET_STR
3391 "BGP extended community attribute\n"
3392 "Site-of-Origin extended community\n"
3393 "VPN extended community\n")
3394
3395DEFUN (set_origin,
3396 set_origin_cmd,
3397 "set origin (egp|igp|incomplete)",
3398 SET_STR
3399 "BGP origin code\n"
3400 "remote EGP\n"
3401 "local IGP\n"
3402 "unknown heritage\n")
3403{
3404 if (strncmp (argv[0], "igp", 2) == 0)
3405 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3406 if (strncmp (argv[0], "egp", 1) == 0)
3407 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3408 if (strncmp (argv[0], "incomplete", 2) == 0)
3409 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3410
3411 return CMD_WARNING;
3412}
3413
3414DEFUN (no_set_origin,
3415 no_set_origin_cmd,
3416 "no set origin",
3417 NO_STR
3418 SET_STR
3419 "BGP origin code\n")
3420{
3421 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3422}
3423
3424ALIAS (no_set_origin,
3425 no_set_origin_val_cmd,
3426 "no set origin (egp|igp|incomplete)",
3427 NO_STR
3428 SET_STR
3429 "BGP origin code\n"
3430 "remote EGP\n"
3431 "local IGP\n"
3432 "unknown heritage\n")
3433
3434DEFUN (set_atomic_aggregate,
3435 set_atomic_aggregate_cmd,
3436 "set atomic-aggregate",
3437 SET_STR
3438 "BGP atomic aggregate attribute\n" )
3439{
3440 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3441}
3442
3443DEFUN (no_set_atomic_aggregate,
3444 no_set_atomic_aggregate_cmd,
3445 "no set atomic-aggregate",
3446 NO_STR
3447 SET_STR
3448 "BGP atomic aggregate attribute\n" )
3449{
3450 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3451}
3452
3453DEFUN (set_aggregator_as,
3454 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003455 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003456 SET_STR
3457 "BGP aggregator attribute\n"
3458 "AS number of aggregator\n"
3459 "AS number\n"
3460 "IP address of aggregator\n")
3461{
3462 int ret;
3463 as_t as;
3464 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003465 char *argstr;
3466
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003467 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003468
paul718e3742002-12-13 20:15:29 +00003469 ret = inet_aton (argv[1], &address);
3470 if (ret == 0)
3471 {
3472 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3473 return CMD_WARNING;
3474 }
3475
3476 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3477 strlen (argv[0]) + strlen (argv[1]) + 2);
3478
3479 sprintf (argstr, "%s %s", argv[0], argv[1]);
3480
3481 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3482
3483 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3484
3485 return ret;
3486}
3487
3488DEFUN (no_set_aggregator_as,
3489 no_set_aggregator_as_cmd,
3490 "no set aggregator as",
3491 NO_STR
3492 SET_STR
3493 "BGP aggregator attribute\n"
3494 "AS number of aggregator\n")
3495{
3496 int ret;
3497 as_t as;
3498 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003499 char *argstr;
3500
3501 if (argv == 0)
3502 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3503
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003504 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003505
3506 ret = inet_aton (argv[1], &address);
3507 if (ret == 0)
3508 {
3509 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3510 return CMD_WARNING;
3511 }
3512
3513 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3514 strlen (argv[0]) + strlen (argv[1]) + 2);
3515
3516 sprintf (argstr, "%s %s", argv[0], argv[1]);
3517
3518 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3519
3520 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3521
3522 return ret;
3523}
3524
3525ALIAS (no_set_aggregator_as,
3526 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003527 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003528 NO_STR
3529 SET_STR
3530 "BGP aggregator attribute\n"
3531 "AS number of aggregator\n"
3532 "AS number\n"
3533 "IP address of aggregator\n")
3534
3535
3536#ifdef HAVE_IPV6
3537DEFUN (match_ipv6_address,
3538 match_ipv6_address_cmd,
3539 "match ipv6 address WORD",
3540 MATCH_STR
3541 IPV6_STR
3542 "Match IPv6 address of route\n"
3543 "IPv6 access-list name\n")
3544{
3545 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3546}
3547
3548DEFUN (no_match_ipv6_address,
3549 no_match_ipv6_address_cmd,
3550 "no match ipv6 address WORD",
3551 NO_STR
3552 MATCH_STR
3553 IPV6_STR
3554 "Match IPv6 address of route\n"
3555 "IPv6 access-list name\n")
3556{
3557 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3558}
3559
3560DEFUN (match_ipv6_next_hop,
3561 match_ipv6_next_hop_cmd,
3562 "match ipv6 next-hop X:X::X:X",
3563 MATCH_STR
3564 IPV6_STR
3565 "Match IPv6 next-hop address of route\n"
3566 "IPv6 address of next hop\n")
3567{
3568 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3569}
3570
3571DEFUN (no_match_ipv6_next_hop,
3572 no_match_ipv6_next_hop_cmd,
3573 "no match ipv6 next-hop X:X::X:X",
3574 NO_STR
3575 MATCH_STR
3576 IPV6_STR
3577 "Match IPv6 next-hop address of route\n"
3578 "IPv6 address of next hop\n")
3579{
3580 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3581}
3582
3583DEFUN (match_ipv6_address_prefix_list,
3584 match_ipv6_address_prefix_list_cmd,
3585 "match ipv6 address prefix-list WORD",
3586 MATCH_STR
3587 IPV6_STR
3588 "Match address of route\n"
3589 "Match entries of prefix-lists\n"
3590 "IP prefix-list name\n")
3591{
3592 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3593}
3594
3595DEFUN (no_match_ipv6_address_prefix_list,
3596 no_match_ipv6_address_prefix_list_cmd,
3597 "no match ipv6 address prefix-list WORD",
3598 NO_STR
3599 MATCH_STR
3600 IPV6_STR
3601 "Match address of route\n"
3602 "Match entries of prefix-lists\n"
3603 "IP prefix-list name\n")
3604{
3605 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3606}
3607
3608DEFUN (set_ipv6_nexthop_global,
3609 set_ipv6_nexthop_global_cmd,
3610 "set ipv6 next-hop global X:X::X:X",
3611 SET_STR
3612 IPV6_STR
3613 "IPv6 next-hop address\n"
3614 "IPv6 global address\n"
3615 "IPv6 address of next hop\n")
3616{
3617 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3618}
3619
3620DEFUN (no_set_ipv6_nexthop_global,
3621 no_set_ipv6_nexthop_global_cmd,
3622 "no set ipv6 next-hop global",
3623 NO_STR
3624 SET_STR
3625 IPV6_STR
3626 "IPv6 next-hop address\n"
3627 "IPv6 global address\n")
3628{
3629 if (argc == 0)
3630 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3631
3632 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3633}
3634
3635ALIAS (no_set_ipv6_nexthop_global,
3636 no_set_ipv6_nexthop_global_val_cmd,
3637 "no set ipv6 next-hop global X:X::X:X",
3638 NO_STR
3639 SET_STR
3640 IPV6_STR
3641 "IPv6 next-hop address\n"
3642 "IPv6 global address\n"
3643 "IPv6 address of next hop\n")
3644
3645DEFUN (set_ipv6_nexthop_local,
3646 set_ipv6_nexthop_local_cmd,
3647 "set ipv6 next-hop local X:X::X:X",
3648 SET_STR
3649 IPV6_STR
3650 "IPv6 next-hop address\n"
3651 "IPv6 local address\n"
3652 "IPv6 address of next hop\n")
3653{
3654 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3655}
3656
3657DEFUN (no_set_ipv6_nexthop_local,
3658 no_set_ipv6_nexthop_local_cmd,
3659 "no set ipv6 next-hop local",
3660 NO_STR
3661 SET_STR
3662 IPV6_STR
3663 "IPv6 next-hop address\n"
3664 "IPv6 local address\n")
3665{
3666 if (argc == 0)
3667 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3668
3669 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3670}
3671
3672ALIAS (no_set_ipv6_nexthop_local,
3673 no_set_ipv6_nexthop_local_val_cmd,
3674 "no set ipv6 next-hop local X:X::X:X",
3675 NO_STR
3676 SET_STR
3677 IPV6_STR
3678 "IPv6 next-hop address\n"
3679 "IPv6 local address\n"
3680 "IPv6 address of next hop\n")
3681#endif /* HAVE_IPV6 */
3682
3683DEFUN (set_vpnv4_nexthop,
3684 set_vpnv4_nexthop_cmd,
3685 "set vpnv4 next-hop A.B.C.D",
3686 SET_STR
3687 "VPNv4 information\n"
3688 "VPNv4 next-hop address\n"
3689 "IP address of next hop\n")
3690{
3691 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3692}
3693
3694DEFUN (no_set_vpnv4_nexthop,
3695 no_set_vpnv4_nexthop_cmd,
3696 "no set vpnv4 next-hop",
3697 NO_STR
3698 SET_STR
3699 "VPNv4 information\n"
3700 "VPNv4 next-hop address\n")
3701{
3702 if (argc == 0)
3703 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3704
3705 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3706}
3707
3708ALIAS (no_set_vpnv4_nexthop,
3709 no_set_vpnv4_nexthop_val_cmd,
3710 "no set vpnv4 next-hop A.B.C.D",
3711 NO_STR
3712 SET_STR
3713 "VPNv4 information\n"
3714 "VPNv4 next-hop address\n"
3715 "IP address of next hop\n")
3716
3717DEFUN (set_originator_id,
3718 set_originator_id_cmd,
3719 "set originator-id A.B.C.D",
3720 SET_STR
3721 "BGP originator ID attribute\n"
3722 "IP address of originator\n")
3723{
3724 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3725}
3726
3727DEFUN (no_set_originator_id,
3728 no_set_originator_id_cmd,
3729 "no set originator-id",
3730 NO_STR
3731 SET_STR
3732 "BGP originator ID attribute\n")
3733{
3734 if (argc == 0)
3735 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3736
3737 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3738}
3739
3740ALIAS (no_set_originator_id,
3741 no_set_originator_id_val_cmd,
3742 "no set originator-id A.B.C.D",
3743 NO_STR
3744 SET_STR
3745 "BGP originator ID attribute\n"
3746 "IP address of originator\n")
3747
Paul Jakma41367172007-08-06 15:24:51 +00003748DEFUN (set_pathlimit_ttl,
3749 set_pathlimit_ttl_cmd,
3750 "set pathlimit ttl <1-255>",
3751 SET_STR
3752 "BGP AS-Pathlimit attribute\n"
3753 "Set AS-Path Hop-count TTL\n")
3754{
3755 return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]);
3756}
3757
3758DEFUN (no_set_pathlimit_ttl,
3759 no_set_pathlimit_ttl_cmd,
3760 "no set pathlimit ttl",
3761 NO_STR
3762 SET_STR
3763 "BGP AS-Pathlimit attribute\n"
3764 "Set AS-Path Hop-count TTL\n")
3765{
3766 if (argc == 0)
3767 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL);
3768
3769 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]);
3770}
3771
3772ALIAS (no_set_pathlimit_ttl,
3773 no_set_pathlimit_ttl_val_cmd,
3774 "no set pathlimit ttl <1-255>",
3775 NO_STR
3776 MATCH_STR
3777 "BGP AS-Pathlimit attribute\n"
3778 "Set AS-Path Hop-count TTL\n")
3779
3780DEFUN (match_pathlimit_as,
3781 match_pathlimit_as_cmd,
3782 "match pathlimit as <1-65535>",
3783 MATCH_STR
3784 "BGP AS-Pathlimit attribute\n"
3785 "Match Pathlimit AS number\n")
3786{
3787 return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]);
3788}
3789
3790DEFUN (no_match_pathlimit_as,
3791 no_match_pathlimit_as_cmd,
3792 "no match pathlimit as",
3793 NO_STR
3794 MATCH_STR
3795 "BGP AS-Pathlimit attribute\n"
3796 "Match Pathlimit AS number\n")
3797{
3798 if (argc == 0)
3799 return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL);
3800
3801 return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]);
3802}
3803
3804ALIAS (no_match_pathlimit_as,
3805 no_match_pathlimit_as_val_cmd,
3806 "no match pathlimit as <1-65535>",
3807 NO_STR
3808 MATCH_STR
3809 "BGP AS-Pathlimit attribute\n"
3810 "Match Pathlimit ASN\n")
3811
paul718e3742002-12-13 20:15:29 +00003812
3813/* Initialization of route map. */
3814void
paul94f2b392005-06-28 12:44:16 +00003815bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003816{
3817 route_map_init ();
3818 route_map_init_vty ();
3819 route_map_add_hook (bgp_route_map_update);
3820 route_map_delete_hook (bgp_route_map_update);
3821
paulfee0f4c2004-09-13 05:12:46 +00003822 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003823 route_map_install_match (&route_match_ip_address_cmd);
3824 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003825 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003826 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3827 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003828 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003829 route_map_install_match (&route_match_aspath_cmd);
3830 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003831 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003832 route_map_install_match (&route_match_metric_cmd);
3833 route_map_install_match (&route_match_origin_cmd);
3834
3835 route_map_install_set (&route_set_ip_nexthop_cmd);
3836 route_map_install_set (&route_set_local_pref_cmd);
3837 route_map_install_set (&route_set_weight_cmd);
3838 route_map_install_set (&route_set_metric_cmd);
3839 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003840 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003841 route_map_install_set (&route_set_origin_cmd);
3842 route_map_install_set (&route_set_atomic_aggregate_cmd);
3843 route_map_install_set (&route_set_aggregator_as_cmd);
3844 route_map_install_set (&route_set_community_cmd);
3845 route_map_install_set (&route_set_community_delete_cmd);
3846 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3847 route_map_install_set (&route_set_originator_id_cmd);
3848 route_map_install_set (&route_set_ecommunity_rt_cmd);
3849 route_map_install_set (&route_set_ecommunity_soo_cmd);
3850
paulfee0f4c2004-09-13 05:12:46 +00003851 install_element (RMAP_NODE, &match_peer_cmd);
3852 install_element (RMAP_NODE, &match_peer_local_cmd);
3853 install_element (RMAP_NODE, &no_match_peer_cmd);
3854 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3855 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003856 install_element (RMAP_NODE, &match_ip_address_cmd);
3857 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3858 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3859 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3860 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3861 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003862 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3863 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3864 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003865
3866 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3867 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3868 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3869 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3870 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3871 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003872 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3873 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3874 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003875
3876 install_element (RMAP_NODE, &match_aspath_cmd);
3877 install_element (RMAP_NODE, &no_match_aspath_cmd);
3878 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3879 install_element (RMAP_NODE, &match_metric_cmd);
3880 install_element (RMAP_NODE, &no_match_metric_cmd);
3881 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3882 install_element (RMAP_NODE, &match_community_cmd);
3883 install_element (RMAP_NODE, &match_community_exact_cmd);
3884 install_element (RMAP_NODE, &no_match_community_cmd);
3885 install_element (RMAP_NODE, &no_match_community_val_cmd);
3886 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003887 install_element (RMAP_NODE, &match_ecommunity_cmd);
3888 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3889 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003890 install_element (RMAP_NODE, &match_origin_cmd);
3891 install_element (RMAP_NODE, &no_match_origin_cmd);
3892 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3893
3894 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003895 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003896 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3897 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3898 install_element (RMAP_NODE, &set_local_pref_cmd);
3899 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3900 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3901 install_element (RMAP_NODE, &set_weight_cmd);
3902 install_element (RMAP_NODE, &no_set_weight_cmd);
3903 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3904 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003905 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003906 install_element (RMAP_NODE, &no_set_metric_cmd);
3907 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3908 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003909 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003910 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3911 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003912 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3913 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003914 install_element (RMAP_NODE, &set_origin_cmd);
3915 install_element (RMAP_NODE, &no_set_origin_cmd);
3916 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3917 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3918 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3919 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3920 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3921 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3922 install_element (RMAP_NODE, &set_community_cmd);
3923 install_element (RMAP_NODE, &set_community_none_cmd);
3924 install_element (RMAP_NODE, &no_set_community_cmd);
3925 install_element (RMAP_NODE, &no_set_community_val_cmd);
3926 install_element (RMAP_NODE, &no_set_community_none_cmd);
3927 install_element (RMAP_NODE, &set_community_delete_cmd);
3928 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3929 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3930 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3931 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3932 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3933 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3934 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3935 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3936 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3937 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3938 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3939 install_element (RMAP_NODE, &set_originator_id_cmd);
3940 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3941 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3942
3943#ifdef HAVE_IPV6
3944 route_map_install_match (&route_match_ipv6_address_cmd);
3945 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3946 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3947 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3948 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003949
paul718e3742002-12-13 20:15:29 +00003950 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3951 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3952 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3953 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3954 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3955 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3956 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3957 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3958 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3959 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3960 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3961 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3962#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003963
3964 /* AS-Pathlimit */
3965 route_map_install_match (&route_match_pathlimit_as_cmd);
3966 route_map_install_set (&route_set_pathlimit_ttl_cmd);
3967
3968 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3969 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3970 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3971 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3972 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3973 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003974}