]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_routemap.c
bgpd/security: CVE-2010-1674 Fix crash due to extended-community parser error
[mirror_frr.git] / bgpd / bgp_routemap.c
CommitLineData
718e3744 1/* 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"
25f45887
JJ
31#ifdef HAVE_LIBPCREPOSIX
32# include <pcreposix.h>
718e3744 33#else
25f45887
JJ
34# ifdef HAVE_GNU_REGEX
35# include <regex.h>
36# else
37# include "regex-gnu.h"
38# endif /* HAVE_GNU_REGEX */
39#endif /* HAVE_LIBPCREPOSIX */
718e3744 40#include "buffer.h"
41#include "sockunion.h"
42
43#include "bgpd/bgpd.h"
44#include "bgpd/bgp_table.h"
45#include "bgpd/bgp_attr.h"
46#include "bgpd/bgp_aspath.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_regex.h"
49#include "bgpd/bgp_community.h"
50#include "bgpd/bgp_clist.h"
51#include "bgpd/bgp_filter.h"
52#include "bgpd/bgp_mplsvpn.h"
53#include "bgpd/bgp_ecommunity.h"
320da874 54#include "bgpd/bgp_vty.h"
718e3744 55
56/* Memo of route-map commands.
57
58o Cisco route-map
59
60 match as-path : Done
61 community : Done
62 interface : Not yet
63 ip address : Done
64 ip next-hop : Done
c1643bb7 65 ip route-source : Done
718e3744 66 ip prefix-list : Done
67 ipv6 address : Done
68 ipv6 next-hop : Done
69 ipv6 route-source: (This will not be implemented by bgpd)
70 ipv6 prefix-list : Done
71 length : (This will not be implemented by bgpd)
72 metric : Done
73 route-type : (This will not be implemented by bgpd)
74 tag : (This will not be implemented by bgpd)
75
76 set as-path prepend : Done
77 as-path tag : Not yet
78 automatic-tag : (This will not be implemented by bgpd)
79 community : Done
80 comm-list : Not yet
81 dampning : Not yet
82 default : (This will not be implemented by bgpd)
83 interface : (This will not be implemented by bgpd)
84 ip default : (This will not be implemented by bgpd)
85 ip next-hop : Done
86 ip precedence : (This will not be implemented by bgpd)
87 ip tos : (This will not be implemented by bgpd)
88 level : (This will not be implemented by bgpd)
89 local-preference : Done
90 metric : Done
91 metric-type : Not yet
92 origin : Done
93 tag : (This will not be implemented by bgpd)
94 weight : Done
41367172 95 pathlimit : Done
718e3744 96
97o Local extention
98
99 set ipv6 next-hop global: Done
100 set ipv6 next-hop local : Done
41367172 101 set pathlimit ttl : Done
841f7a57 102 set as-path exclude : Done
41367172 103 match pathlimit as : Done
718e3744 104
105*/
41367172
PJ
106\f
107/* Compiles either AS or TTL argument. It is amused the VTY code
108 * has already range-checked the values to be suitable as TTL or ASN
109 */
110static void *
111route_pathlimit_compile (const char *arg)
112{
113 unsigned long tmp;
114 u_int32_t *val;
115 char *endptr = NULL;
116
117 /* TTL or AS value shoud be integer. */
118 if (! all_digit (arg))
119 return NULL;
120
121 tmp = strtoul (arg, &endptr, 10);
122 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
123 return NULL;
124
125 if (!(val = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t))))
126 return NULL;
127
128 *val = tmp;
129
130 return val;
131}
132
133static void
134route_pathlimit_free (void *rule)
135{
136 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
137}
138
139static route_map_result_t
140route_match_pathlimit_as (void *rule, struct prefix *prefix, route_map_object_t type,
141 void *object)
142{
143 struct bgp_info *info = object;
144 struct attr *attr = info->attr;
145 uint32_t as = *(uint32_t *)rule;
146
147 if (type != RMAP_BGP)
148 return RMAP_NOMATCH;
149
150 if (!attr->pathlimit.as)
151 return RMAP_NOMATCH;
152
153 if (as == attr->pathlimit.as)
154 return RMAP_MATCH;
155
156 return RMAP_NOMATCH;
157}
158
159/* 'match pathlimit as' */
160struct route_map_rule_cmd route_match_pathlimit_as_cmd =
161{
162 "pathlimit as",
163 route_match_pathlimit_as,
164 route_pathlimit_compile,
165 route_pathlimit_free
166};
167
168/* Set pathlimit TTL. */
169static route_map_result_t
170route_set_pathlimit_ttl (void *rule, struct prefix *prefix,
171 route_map_object_t type, void *object)
172{
173 struct bgp_info *info = object;
174 struct attr *attr = info->attr;
175 u_char ttl = *(uint32_t *)rule;
176
177 if (type == RMAP_BGP)
178 {
179 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
180 attr->pathlimit.ttl = ttl;
181 attr->pathlimit.as = 0;
182 }
183
184 return RMAP_OKAY;
185}
186
187/* Set local preference rule structure. */
188struct route_map_rule_cmd route_set_pathlimit_ttl_cmd =
189{
190 "pathlimit ttl",
191 route_set_pathlimit_ttl,
192 route_pathlimit_compile,
193 route_pathlimit_free,
194};
718e3744 195\f
fee0f4c6 196 /* 'match peer (A.B.C.D|X:X::X:X)' */
197
198/* Compares the peer specified in the 'match peer' clause with the peer
199 received in bgp_info->peer. If it is the same, or if the peer structure
200 received is a peer_group containing it, returns RMAP_MATCH. */
94f2b392 201static route_map_result_t
fee0f4c6 202route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
203 void *object)
204{
205 union sockunion *su;
206 union sockunion *su2;
207 struct peer_group *group;
208 struct peer *peer;
1eb8ef25 209 struct listnode *node, *nnode;
fee0f4c6 210
211 if (type == RMAP_BGP)
212 {
213 su = rule;
214 peer = ((struct bgp_info *) object)->peer;
215
216 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
217 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
218 return RMAP_NOMATCH;
219
220 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
221 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
222 su2 = sockunion_str2su ("0.0.0.0");
223 if ( sockunion_same (su, su2) )
224 {
22db9dec 225 int ret;
fee0f4c6 226 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
227 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
228 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
22db9dec 229 ret = RMAP_MATCH;
fee0f4c6 230 else
22db9dec 231 ret = RMAP_NOMATCH;
232
233 sockunion_free (su2);
234 return ret;
fee0f4c6 235 }
22db9dec 236 sockunion_free (su2);
237
fee0f4c6 238 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
239 {
240 if (sockunion_same (su, &peer->su))
241 return RMAP_MATCH;
242
243 return RMAP_NOMATCH;
244 }
245 else
246 {
247 group = peer->group;
1eb8ef25 248 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
fee0f4c6 249 {
250 if (sockunion_same (su, &peer->su))
251 return RMAP_MATCH;
fee0f4c6 252 }
30a2231a 253 return RMAP_NOMATCH;
fee0f4c6 254 }
255 }
256 return RMAP_NOMATCH;
257}
258
94f2b392 259static void *
fd79ac91 260route_match_peer_compile (const char *arg)
fee0f4c6 261{
262 union sockunion *su;
263 int ret;
264
265 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
266
267 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
268 if (ret < 0) {
269 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
270 return NULL;
271 }
272
273 return su;
274}
275
276/* Free route map's compiled `ip address' value. */
94f2b392 277static void
fee0f4c6 278route_match_peer_free (void *rule)
279{
280 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
281}
282
283/* Route map commands for ip address matching. */
284struct route_map_rule_cmd route_match_peer_cmd =
285{
286 "peer",
287 route_match_peer,
288 route_match_peer_compile,
289 route_match_peer_free
290};
291
718e3744 292/* `match ip address IP_ACCESS_LIST' */
293
294/* Match function should return 1 if match is success else return
295 zero. */
94f2b392 296static route_map_result_t
718e3744 297route_match_ip_address (void *rule, struct prefix *prefix,
298 route_map_object_t type, void *object)
299{
300 struct access_list *alist;
301 /* struct prefix_ipv4 match; */
302
303 if (type == RMAP_BGP)
304 {
305 alist = access_list_lookup (AFI_IP, (char *) rule);
306 if (alist == NULL)
307 return RMAP_NOMATCH;
308
309 return (access_list_apply (alist, prefix) == FILTER_DENY ?
310 RMAP_NOMATCH : RMAP_MATCH);
311 }
312 return RMAP_NOMATCH;
313}
314
315/* Route map `ip address' match statement. `arg' should be
316 access-list name. */
94f2b392 317static void *
fd79ac91 318route_match_ip_address_compile (const char *arg)
718e3744 319{
320 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
321}
322
323/* Free route map's compiled `ip address' value. */
94f2b392 324static void
718e3744 325route_match_ip_address_free (void *rule)
326{
327 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
328}
329
330/* Route map commands for ip address matching. */
331struct route_map_rule_cmd route_match_ip_address_cmd =
332{
333 "ip address",
334 route_match_ip_address,
335 route_match_ip_address_compile,
336 route_match_ip_address_free
337};
338\f
339/* `match ip next-hop IP_ADDRESS' */
340
341/* Match function return 1 if match is success else return zero. */
94f2b392 342static route_map_result_t
718e3744 343route_match_ip_next_hop (void *rule, struct prefix *prefix,
344 route_map_object_t type, void *object)
345{
346 struct access_list *alist;
347 struct bgp_info *bgp_info;
348 struct prefix_ipv4 p;
349
350 if (type == RMAP_BGP)
351 {
352 bgp_info = object;
353 p.family = AF_INET;
354 p.prefix = bgp_info->attr->nexthop;
355 p.prefixlen = IPV4_MAX_BITLEN;
356
357 alist = access_list_lookup (AFI_IP, (char *) rule);
358 if (alist == NULL)
359 return RMAP_NOMATCH;
360
361 return (access_list_apply (alist, &p) == FILTER_DENY ?
362 RMAP_NOMATCH : RMAP_MATCH);
363 }
364 return RMAP_NOMATCH;
365}
366
367/* Route map `ip next-hop' match statement. `arg' is
368 access-list name. */
94f2b392 369static void *
fd79ac91 370route_match_ip_next_hop_compile (const char *arg)
718e3744 371{
372 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
373}
374
375/* Free route map's compiled `ip address' value. */
94f2b392 376static void
718e3744 377route_match_ip_next_hop_free (void *rule)
378{
379 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
380}
381
382/* Route map commands for ip next-hop matching. */
383struct route_map_rule_cmd route_match_ip_next_hop_cmd =
384{
385 "ip next-hop",
386 route_match_ip_next_hop,
387 route_match_ip_next_hop_compile,
388 route_match_ip_next_hop_free
389};
390\f
c1643bb7 391/* `match ip route-source ACCESS-LIST' */
392
393/* Match function return 1 if match is success else return zero. */
94f2b392 394static route_map_result_t
c1643bb7 395route_match_ip_route_source (void *rule, struct prefix *prefix,
396 route_map_object_t type, void *object)
397{
398 struct access_list *alist;
399 struct bgp_info *bgp_info;
400 struct peer *peer;
401 struct prefix_ipv4 p;
402
403 if (type == RMAP_BGP)
404 {
405 bgp_info = object;
406 peer = bgp_info->peer;
407
408 if (! peer || sockunion_family (&peer->su) != AF_INET)
409 return RMAP_NOMATCH;
410
411 p.family = AF_INET;
412 p.prefix = peer->su.sin.sin_addr;
413 p.prefixlen = IPV4_MAX_BITLEN;
414
415 alist = access_list_lookup (AFI_IP, (char *) rule);
416 if (alist == NULL)
417 return RMAP_NOMATCH;
418
419 return (access_list_apply (alist, &p) == FILTER_DENY ?
420 RMAP_NOMATCH : RMAP_MATCH);
421 }
422 return RMAP_NOMATCH;
423}
424
425/* Route map `ip route-source' match statement. `arg' is
426 access-list name. */
94f2b392 427static void *
c1643bb7 428route_match_ip_route_source_compile (const char *arg)
429{
430 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
431}
432
433/* Free route map's compiled `ip address' value. */
94f2b392 434static void
c1643bb7 435route_match_ip_route_source_free (void *rule)
436{
437 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
438}
439
440/* Route map commands for ip route-source matching. */
441struct route_map_rule_cmd route_match_ip_route_source_cmd =
442{
443 "ip route-source",
444 route_match_ip_route_source,
445 route_match_ip_route_source_compile,
446 route_match_ip_route_source_free
447};
448\f
718e3744 449/* `match ip address prefix-list PREFIX_LIST' */
450
94f2b392 451static route_map_result_t
718e3744 452route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
453 route_map_object_t type, void *object)
454{
455 struct prefix_list *plist;
456
457 if (type == RMAP_BGP)
458 {
459 plist = prefix_list_lookup (AFI_IP, (char *) rule);
460 if (plist == NULL)
461 return RMAP_NOMATCH;
462
463 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
464 RMAP_NOMATCH : RMAP_MATCH);
465 }
466 return RMAP_NOMATCH;
467}
468
94f2b392 469static void *
fd79ac91 470route_match_ip_address_prefix_list_compile (const char *arg)
718e3744 471{
472 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
473}
474
94f2b392 475static void
718e3744 476route_match_ip_address_prefix_list_free (void *rule)
477{
478 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
479}
480
481struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
482{
483 "ip address prefix-list",
484 route_match_ip_address_prefix_list,
485 route_match_ip_address_prefix_list_compile,
486 route_match_ip_address_prefix_list_free
487};
488\f
489/* `match ip next-hop prefix-list PREFIX_LIST' */
490
94f2b392 491static route_map_result_t
718e3744 492route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
493 route_map_object_t type, void *object)
494{
495 struct prefix_list *plist;
496 struct bgp_info *bgp_info;
497 struct prefix_ipv4 p;
498
499 if (type == RMAP_BGP)
500 {
501 bgp_info = object;
502 p.family = AF_INET;
503 p.prefix = bgp_info->attr->nexthop;
504 p.prefixlen = IPV4_MAX_BITLEN;
505
506 plist = prefix_list_lookup (AFI_IP, (char *) rule);
507 if (plist == NULL)
508 return RMAP_NOMATCH;
509
510 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
511 RMAP_NOMATCH : RMAP_MATCH);
512 }
513 return RMAP_NOMATCH;
514}
515
94f2b392 516static void *
fd79ac91 517route_match_ip_next_hop_prefix_list_compile (const char *arg)
718e3744 518{
519 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
520}
521
94f2b392 522static void
718e3744 523route_match_ip_next_hop_prefix_list_free (void *rule)
524{
525 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
526}
527
528struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
529{
530 "ip next-hop prefix-list",
531 route_match_ip_next_hop_prefix_list,
532 route_match_ip_next_hop_prefix_list_compile,
533 route_match_ip_next_hop_prefix_list_free
534};
535\f
c1643bb7 536/* `match ip route-source prefix-list PREFIX_LIST' */
537
94f2b392 538static route_map_result_t
c1643bb7 539route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
540 route_map_object_t type, void *object)
541{
542 struct prefix_list *plist;
543 struct bgp_info *bgp_info;
544 struct peer *peer;
545 struct prefix_ipv4 p;
546
547 if (type == RMAP_BGP)
548 {
549 bgp_info = object;
550 peer = bgp_info->peer;
551
552 if (! peer || sockunion_family (&peer->su) != AF_INET)
553 return RMAP_NOMATCH;
554
555 p.family = AF_INET;
556 p.prefix = peer->su.sin.sin_addr;
557 p.prefixlen = IPV4_MAX_BITLEN;
558
559 plist = prefix_list_lookup (AFI_IP, (char *) rule);
560 if (plist == NULL)
561 return RMAP_NOMATCH;
562
563 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
564 RMAP_NOMATCH : RMAP_MATCH);
565 }
566 return RMAP_NOMATCH;
567}
568
94f2b392 569static void *
c1643bb7 570route_match_ip_route_source_prefix_list_compile (const char *arg)
571{
572 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
573}
574
94f2b392 575static void
c1643bb7 576route_match_ip_route_source_prefix_list_free (void *rule)
577{
578 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
579}
580
581struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
582{
583 "ip route-source prefix-list",
584 route_match_ip_route_source_prefix_list,
585 route_match_ip_route_source_prefix_list_compile,
586 route_match_ip_route_source_prefix_list_free
587};
588\f
718e3744 589/* `match metric METRIC' */
590
591/* Match function return 1 if match is success else return zero. */
94f2b392 592static route_map_result_t
718e3744 593route_match_metric (void *rule, struct prefix *prefix,
594 route_map_object_t type, void *object)
595{
596 u_int32_t *med;
597 struct bgp_info *bgp_info;
598
599 if (type == RMAP_BGP)
600 {
601 med = rule;
602 bgp_info = object;
603
604 if (bgp_info->attr->med == *med)
605 return RMAP_MATCH;
606 else
607 return RMAP_NOMATCH;
608 }
609 return RMAP_NOMATCH;
610}
611
612/* Route map `match metric' match statement. `arg' is MED value */
94f2b392 613static void *
fd79ac91 614route_match_metric_compile (const char *arg)
718e3744 615{
616 u_int32_t *med;
617 char *endptr = NULL;
3b424979 618 unsigned long tmpval;
718e3744 619
3b424979 620 tmpval = strtoul (arg, &endptr, 10);
fd79ac91 621 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
3b424979 622 return NULL;
fd79ac91 623
718e3744 624 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
fd79ac91 625
626 if (!med)
627 return med;
628
3b424979 629 *med = tmpval;
718e3744 630 return med;
631}
632
633/* Free route map's compiled `match metric' value. */
94f2b392 634static void
718e3744 635route_match_metric_free (void *rule)
636{
637 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
638}
639
640/* Route map commands for metric matching. */
641struct route_map_rule_cmd route_match_metric_cmd =
642{
643 "metric",
644 route_match_metric,
645 route_match_metric_compile,
646 route_match_metric_free
647};
648\f
649/* `match as-path ASPATH' */
650
651/* Match function for as-path match. I assume given object is */
94f2b392 652static route_map_result_t
718e3744 653route_match_aspath (void *rule, struct prefix *prefix,
654 route_map_object_t type, void *object)
655{
656
657 struct as_list *as_list;
658 struct bgp_info *bgp_info;
659
660 if (type == RMAP_BGP)
661 {
662 as_list = as_list_lookup ((char *) rule);
663 if (as_list == NULL)
664 return RMAP_NOMATCH;
665
666 bgp_info = object;
667
668 /* Perform match. */
669 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
670 }
671 return RMAP_NOMATCH;
672}
673
674/* Compile function for as-path match. */
94f2b392 675static void *
fd79ac91 676route_match_aspath_compile (const char *arg)
718e3744 677{
678 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
679}
680
681/* Compile function for as-path match. */
94f2b392 682static void
718e3744 683route_match_aspath_free (void *rule)
684{
685 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
686}
687
688/* Route map commands for aspath matching. */
689struct route_map_rule_cmd route_match_aspath_cmd =
690{
691 "as-path",
692 route_match_aspath,
693 route_match_aspath_compile,
694 route_match_aspath_free
695};
718e3744 696\f
697/* `match community COMMUNIY' */
698struct rmap_community
699{
700 char *name;
701 int exact;
702};
703
704/* Match function for community match. */
94f2b392 705static route_map_result_t
718e3744 706route_match_community (void *rule, struct prefix *prefix,
707 route_map_object_t type, void *object)
708{
709 struct community_list *list;
710 struct bgp_info *bgp_info;
711 struct rmap_community *rcom;
712
713 if (type == RMAP_BGP)
714 {
715 bgp_info = object;
716 rcom = rule;
717
fee6e4e4 718 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
718e3744 719 if (! list)
720 return RMAP_NOMATCH;
721
722 if (rcom->exact)
723 {
724 if (community_list_exact_match (bgp_info->attr->community, list))
725 return RMAP_MATCH;
726 }
727 else
728 {
729 if (community_list_match (bgp_info->attr->community, list))
730 return RMAP_MATCH;
731 }
732 }
733 return RMAP_NOMATCH;
734}
735
736/* Compile function for community match. */
94f2b392 737static void *
fd79ac91 738route_match_community_compile (const char *arg)
718e3744 739{
740 struct rmap_community *rcom;
741 int len;
742 char *p;
743
744 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
745
746 p = strchr (arg, ' ');
747 if (p)
748 {
749 len = p - arg;
750 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
751 memcpy (rcom->name, arg, len);
752 rcom->exact = 1;
753 }
754 else
755 {
756 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
757 rcom->exact = 0;
758 }
759 return rcom;
760}
761
762/* Compile function for community match. */
94f2b392 763static void
718e3744 764route_match_community_free (void *rule)
765{
766 struct rmap_community *rcom = rule;
767
768 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
769 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
770}
771
772/* Route map commands for community matching. */
773struct route_map_rule_cmd route_match_community_cmd =
774{
775 "community",
776 route_match_community,
777 route_match_community_compile,
778 route_match_community_free
779};
780\f
73ffb25b 781/* Match function for extcommunity match. */
94f2b392 782static route_map_result_t
73ffb25b 783route_match_ecommunity (void *rule, struct prefix *prefix,
784 route_map_object_t type, void *object)
785{
786 struct community_list *list;
787 struct bgp_info *bgp_info;
788
789 if (type == RMAP_BGP)
790 {
791 bgp_info = object;
fb982c25
PJ
792
793 if (!bgp_info->attr->extra)
794 return RMAP_NOMATCH;
795
73ffb25b 796 list = community_list_lookup (bgp_clist, (char *) rule,
fee6e4e4 797 EXTCOMMUNITY_LIST_MASTER);
73ffb25b 798 if (! list)
799 return RMAP_NOMATCH;
800
fb982c25 801 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
73ffb25b 802 return RMAP_MATCH;
803 }
804 return RMAP_NOMATCH;
805}
806
807/* Compile function for extcommunity match. */
94f2b392 808static void *
fd79ac91 809route_match_ecommunity_compile (const char *arg)
73ffb25b 810{
811 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
812}
813
814/* Compile function for extcommunity match. */
94f2b392 815static void
73ffb25b 816route_match_ecommunity_free (void *rule)
817{
818 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
819}
820
821/* Route map commands for community matching. */
822struct route_map_rule_cmd route_match_ecommunity_cmd =
823{
824 "extcommunity",
825 route_match_ecommunity,
826 route_match_ecommunity_compile,
827 route_match_ecommunity_free
828};
829\f
718e3744 830/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
831 and `address-family vpnv4'. */
832\f
833/* `match origin' */
94f2b392 834static route_map_result_t
718e3744 835route_match_origin (void *rule, struct prefix *prefix,
836 route_map_object_t type, void *object)
837{
838 u_char *origin;
839 struct bgp_info *bgp_info;
840
841 if (type == RMAP_BGP)
842 {
843 origin = rule;
844 bgp_info = object;
845
846 if (bgp_info->attr->origin == *origin)
847 return RMAP_MATCH;
848 }
849
850 return RMAP_NOMATCH;
851}
852
94f2b392 853static void *
fd79ac91 854route_match_origin_compile (const char *arg)
718e3744 855{
856 u_char *origin;
857
858 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
859
860 if (strcmp (arg, "igp") == 0)
861 *origin = 0;
862 else if (strcmp (arg, "egp") == 0)
863 *origin = 1;
864 else
865 *origin = 2;
866
867 return origin;
868}
869
870/* Free route map's compiled `ip address' value. */
94f2b392 871static void
718e3744 872route_match_origin_free (void *rule)
873{
874 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
875}
876
877/* Route map commands for origin matching. */
878struct route_map_rule_cmd route_match_origin_cmd =
879{
880 "origin",
881 route_match_origin,
882 route_match_origin_compile,
883 route_match_origin_free
884};
885/* `set ip next-hop IP_ADDRESS' */
886
887/* Set nexthop to object. ojbect must be pointer to struct attr. */
ac41b2a2 888struct rmap_ip_nexthop_set
889{
890 struct in_addr *address;
891 int peer_address;
892};
893
94f2b392 894static route_map_result_t
718e3744 895route_set_ip_nexthop (void *rule, struct prefix *prefix,
896 route_map_object_t type, void *object)
897{
ac41b2a2 898 struct rmap_ip_nexthop_set *rins = rule;
899 struct in_addr peer_address;
718e3744 900 struct bgp_info *bgp_info;
ac41b2a2 901 struct peer *peer;
718e3744 902
903 if (type == RMAP_BGP)
904 {
718e3744 905 bgp_info = object;
ac41b2a2 906 peer = bgp_info->peer;
907
908 if (rins->peer_address)
909 {
fee0f4c6 910 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
911 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
ac41b2a2 912 && peer->su_remote
913 && sockunion_family (peer->su_remote) == AF_INET)
914 {
915 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
916 bgp_info->attr->nexthop = peer_address;
917 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
918 }
919 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
920 && peer->su_local
921 && sockunion_family (peer->su_local) == AF_INET)
922 {
923 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
924 bgp_info->attr->nexthop = peer_address;
925 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
926 }
927 }
928 else
929 {
930 /* Set next hop value. */
931 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
932 bgp_info->attr->nexthop = *rins->address;
933 }
718e3744 934 }
935
936 return RMAP_OKAY;
937}
938
939/* Route map `ip nexthop' compile function. Given string is converted
940 to struct in_addr structure. */
94f2b392 941static void *
fd79ac91 942route_set_ip_nexthop_compile (const char *arg)
718e3744 943{
ac41b2a2 944 struct rmap_ip_nexthop_set *rins;
945 struct in_addr *address = NULL;
946 int peer_address = 0;
718e3744 947 int ret;
718e3744 948
ac41b2a2 949 if (strcmp (arg, "peer-address") == 0)
950 peer_address = 1;
951 else
718e3744 952 {
ac41b2a2 953 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
954 ret = inet_aton (arg, address);
955
956 if (ret == 0)
957 {
958 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
959 return NULL;
960 }
718e3744 961 }
962
393deb9b 963 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
ac41b2a2 964
965 rins->address = address;
966 rins->peer_address = peer_address;
967
968 return rins;
718e3744 969}
970
971/* Free route map's compiled `ip nexthop' value. */
94f2b392 972static void
718e3744 973route_set_ip_nexthop_free (void *rule)
974{
ac41b2a2 975 struct rmap_ip_nexthop_set *rins = rule;
976
977 if (rins->address)
978 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
979
980 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
718e3744 981}
982
983/* Route map commands for ip nexthop set. */
984struct route_map_rule_cmd route_set_ip_nexthop_cmd =
985{
986 "ip next-hop",
987 route_set_ip_nexthop,
988 route_set_ip_nexthop_compile,
989 route_set_ip_nexthop_free
990};
991\f
992/* `set local-preference LOCAL_PREF' */
993
994/* Set local preference. */
94f2b392 995static route_map_result_t
718e3744 996route_set_local_pref (void *rule, struct prefix *prefix,
997 route_map_object_t type, void *object)
998{
999 u_int32_t *local_pref;
1000 struct bgp_info *bgp_info;
1001
1002 if (type == RMAP_BGP)
1003 {
1004 /* Fetch routemap's rule information. */
1005 local_pref = rule;
1006 bgp_info = object;
1007
1008 /* Set local preference value. */
1009 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1010 bgp_info->attr->local_pref = *local_pref;
1011 }
1012
1013 return RMAP_OKAY;
1014}
1015
1016/* set local preference compilation. */
94f2b392 1017static void *
fd79ac91 1018route_set_local_pref_compile (const char *arg)
718e3744 1019{
fd79ac91 1020 unsigned long tmp;
718e3744 1021 u_int32_t *local_pref;
1022 char *endptr = NULL;
1023
1024 /* Local preference value shoud be integer. */
1025 if (! all_digit (arg))
1026 return NULL;
fd79ac91 1027
1028 tmp = strtoul (arg, &endptr, 10);
1029 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1030 return NULL;
1031
1032 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1033
1034 if (!local_pref)
1035 return local_pref;
1036
1037 *local_pref = tmp;
1038
718e3744 1039 return local_pref;
1040}
1041
1042/* Free route map's local preference value. */
94f2b392 1043static void
718e3744 1044route_set_local_pref_free (void *rule)
1045{
1046 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1047}
1048
1049/* Set local preference rule structure. */
1050struct route_map_rule_cmd route_set_local_pref_cmd =
1051{
1052 "local-preference",
1053 route_set_local_pref,
1054 route_set_local_pref_compile,
1055 route_set_local_pref_free,
1056};
1057\f
1058/* `set weight WEIGHT' */
1059
1060/* Set weight. */
94f2b392 1061static route_map_result_t
718e3744 1062route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1063 void *object)
1064{
1065 u_int32_t *weight;
1066 struct bgp_info *bgp_info;
1067
1068 if (type == RMAP_BGP)
1069 {
1070 /* Fetch routemap's rule information. */
1071 weight = rule;
1072 bgp_info = object;
1073
1074 /* Set weight value. */
fb982c25
PJ
1075 if (*weight)
1076 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1077 else if (bgp_info->attr->extra)
1078 bgp_info->attr->extra->weight = 0;
718e3744 1079 }
1080
1081 return RMAP_OKAY;
1082}
1083
1084/* set local preference compilation. */
94f2b392 1085static void *
fd79ac91 1086route_set_weight_compile (const char *arg)
718e3744 1087{
fd79ac91 1088 unsigned long tmp;
718e3744 1089 u_int32_t *weight;
1090 char *endptr = NULL;
1091
1092 /* Local preference value shoud be integer. */
1093 if (! all_digit (arg))
1094 return NULL;
1095
fd79ac91 1096
1097 tmp = strtoul (arg, &endptr, 10);
1098 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1099 return NULL;
1100
718e3744 1101 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
fd79ac91 1102
1103 if (weight == NULL)
1104 return weight;
1105
1106 *weight = tmp;
1107
718e3744 1108 return weight;
1109}
1110
1111/* Free route map's local preference value. */
94f2b392 1112static void
718e3744 1113route_set_weight_free (void *rule)
1114{
1115 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1116}
1117
1118/* Set local preference rule structure. */
1119struct route_map_rule_cmd route_set_weight_cmd =
1120{
1121 "weight",
1122 route_set_weight,
1123 route_set_weight_compile,
1124 route_set_weight_free,
1125};
1126\f
1127/* `set metric METRIC' */
1128
1129/* Set metric to attribute. */
94f2b392 1130static route_map_result_t
718e3744 1131route_set_metric (void *rule, struct prefix *prefix,
1132 route_map_object_t type, void *object)
1133{
1134 char *metric;
1135 u_int32_t metric_val;
1136 struct bgp_info *bgp_info;
1137
1138 if (type == RMAP_BGP)
1139 {
1140 /* Fetch routemap's rule information. */
1141 metric = rule;
1142 bgp_info = object;
1143
1144 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1145 bgp_info->attr->med = 0;
1146 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1147
1148 if (all_digit (metric))
1149 {
1150 metric_val = strtoul (metric, (char **)NULL, 10);
1151 bgp_info->attr->med = metric_val;
1152 }
1153 else
1154 {
1155 metric_val = strtoul (metric+1, (char **)NULL, 10);
1156
1157 if (strncmp (metric, "+", 1) == 0)
1158 {
3b424979 1159 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1160 bgp_info->attr->med = BGP_MED_MAX - 1;
718e3744 1161 else
537d8ea9 1162 bgp_info->attr->med += metric_val;
718e3744 1163 }
1164 else if (strncmp (metric, "-", 1) == 0)
1165 {
537d8ea9 1166 if (bgp_info->attr->med <= metric_val)
1167 bgp_info->attr->med = 0;
718e3744 1168 else
537d8ea9 1169 bgp_info->attr->med -= metric_val;
718e3744 1170 }
1171 }
1172 }
1173 return RMAP_OKAY;
1174}
1175
1176/* set metric compilation. */
94f2b392 1177static void *
fd79ac91 1178route_set_metric_compile (const char *arg)
718e3744 1179{
1180 u_int32_t metric;
94f2b392 1181 unsigned long larg;
718e3744 1182 char *endptr = NULL;
1183
1184 if (all_digit (arg))
1185 {
1186 /* set metric value check*/
94f2b392 1187 larg = strtoul (arg, &endptr, 10);
1188 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
718e3744 1189 return NULL;
94f2b392 1190 metric = larg;
718e3744 1191 }
1192 else
1193 {
1194 /* set metric +/-value check */
1195 if ((strncmp (arg, "+", 1) != 0
1196 && strncmp (arg, "-", 1) != 0)
1197 || (! all_digit (arg+1)))
1198 return NULL;
1199
94f2b392 1200 larg = strtoul (arg+1, &endptr, 10);
1201 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
718e3744 1202 return NULL;
94f2b392 1203 metric = larg;
718e3744 1204 }
1205
1206 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1207}
1208
1209/* Free route map's compiled `set metric' value. */
94f2b392 1210static void
718e3744 1211route_set_metric_free (void *rule)
1212{
1213 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1214}
1215
1216/* Set metric rule structure. */
1217struct route_map_rule_cmd route_set_metric_cmd =
1218{
1219 "metric",
1220 route_set_metric,
1221 route_set_metric_compile,
1222 route_set_metric_free,
1223};
1224\f
1225/* `set as-path prepend ASPATH' */
1226
1227/* For AS path prepend mechanism. */
94f2b392 1228static route_map_result_t
718e3744 1229route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1230{
1231 struct aspath *aspath;
1232 struct aspath *new;
1233 struct bgp_info *binfo;
1234
1235 if (type == RMAP_BGP)
1236 {
1237 aspath = rule;
1238 binfo = object;
1239
1240 if (binfo->attr->aspath->refcnt)
1241 new = aspath_dup (binfo->attr->aspath);
1242 else
1243 new = binfo->attr->aspath;
1244
1245 aspath_prepend (aspath, new);
1246 binfo->attr->aspath = new;
1247 }
1248
1249 return RMAP_OKAY;
1250}
1251
1252/* Compile function for as-path prepend. */
94f2b392 1253static void *
fd79ac91 1254route_set_aspath_prepend_compile (const char *arg)
718e3744 1255{
1256 struct aspath *aspath;
1257
1258 aspath = aspath_str2aspath (arg);
1259 if (! aspath)
1260 return NULL;
1261 return aspath;
1262}
1263
1264/* Compile function for as-path prepend. */
94f2b392 1265static void
718e3744 1266route_set_aspath_prepend_free (void *rule)
1267{
1268 struct aspath *aspath = rule;
1269 aspath_free (aspath);
1270}
1271
1272/* Set metric rule structure. */
1273struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1274{
1275 "as-path prepend",
1276 route_set_aspath_prepend,
1277 route_set_aspath_prepend_compile,
1278 route_set_aspath_prepend_free,
1279};
1280\f
841f7a57
DO
1281/* `set as-path exclude ASn' */
1282
1283/* For ASN exclude mechanism.
1284 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1285 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1286 */
1287static route_map_result_t
1288route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1289{
1290 struct aspath * new_path, * exclude_path;
1291 struct bgp_info *binfo;
1292
1293 if (type == RMAP_BGP)
1294 {
1295 exclude_path = rule;
1296 binfo = object;
1297 if (binfo->attr->aspath->refcnt)
1298 new_path = aspath_dup (binfo->attr->aspath);
1299 else
1300 new_path = binfo->attr->aspath;
1301 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1302 }
1303 return RMAP_OKAY;
1304}
1305
1306/* FIXME: consider using route_set_aspath_prepend_compile() and
1307 * route_set_aspath_prepend_free(), which two below function are
1308 * exact clones of.
1309 */
1310
1311/* Compile function for as-path exclude. */
1312static void *
1313route_set_aspath_exclude_compile (const char *arg)
1314{
1315 struct aspath *aspath;
1316
1317 aspath = aspath_str2aspath (arg);
1318 if (! aspath)
1319 return NULL;
1320 return aspath;
1321}
1322
1323static void
1324route_set_aspath_exclude_free (void *rule)
1325{
1326 struct aspath *aspath = rule;
1327 aspath_free (aspath);
1328}
1329
1330/* Set ASn exlude rule structure. */
1331struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1332{
1333 "as-path exclude",
1334 route_set_aspath_exclude,
1335 route_set_aspath_exclude_compile,
1336 route_set_aspath_exclude_free,
1337};
1338\f
718e3744 1339/* `set community COMMUNITY' */
1340struct rmap_com_set
1341{
1342 struct community *com;
1343 int additive;
1344 int none;
1345};
1346
1347/* For community set mechanism. */
94f2b392 1348static route_map_result_t
718e3744 1349route_set_community (void *rule, struct prefix *prefix,
1350 route_map_object_t type, void *object)
1351{
1352 struct rmap_com_set *rcs;
1353 struct bgp_info *binfo;
1354 struct attr *attr;
1355 struct community *new = NULL;
1356 struct community *old;
1357 struct community *merge;
aa94ca86 1358
718e3744 1359 if (type == RMAP_BGP)
1360 {
1361 rcs = rule;
1362 binfo = object;
1363 attr = binfo->attr;
1364 old = attr->community;
1365
1366 /* "none" case. */
1367 if (rcs->none)
1368 {
1369 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1370 attr->community = NULL;
1371 return RMAP_OKAY;
1372 }
1373
1374 /* "additive" case. */
1375 if (rcs->additive && old)
1376 {
1377 merge = community_merge (community_dup (old), rcs->com);
aa94ca86
PJ
1378
1379 /* HACK: if the old community is not intern'd,
1380 * we should free it here, or all reference to it may be lost.
1381 * Really need to cleanup attribute caching sometime.
1382 */
1383 if (old->refcnt == 0)
1384 community_free (old);
718e3744 1385 new = community_uniq_sort (merge);
1386 community_free (merge);
1387 }
1388 else
1389 new = community_dup (rcs->com);
aa94ca86
PJ
1390
1391 /* will be interned by caller if required */
718e3744 1392 attr->community = new;
70601e06 1393
718e3744 1394 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1395 }
1396
1397 return RMAP_OKAY;
1398}
1399
1400/* Compile function for set community. */
94f2b392 1401static void *
fd79ac91 1402route_set_community_compile (const char *arg)
718e3744 1403{
1404 struct rmap_com_set *rcs;
1405 struct community *com = NULL;
1406 char *sp;
1407 int additive = 0;
1408 int none = 0;
1409
1410 if (strcmp (arg, "none") == 0)
1411 none = 1;
1412 else
1413 {
1414 sp = strstr (arg, "additive");
1415
1416 if (sp && sp > arg)
1417 {
1418 /* "additive" keyworkd is included. */
1419 additive = 1;
1420 *(sp - 1) = '\0';
1421 }
1422
1423 com = community_str2com (arg);
1424
1425 if (additive)
1426 *(sp - 1) = ' ';
1427
1428 if (! com)
1429 return NULL;
1430 }
1431
393deb9b 1432 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
718e3744 1433 rcs->com = com;
1434 rcs->additive = additive;
1435 rcs->none = none;
1436
1437 return rcs;
1438}
1439
1440/* Free function for set community. */
94f2b392 1441static void
718e3744 1442route_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\f
fee6e4e4 1460/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
718e3744 1461
1462/* For community set mechanism. */
94f2b392 1463static route_map_result_t
718e3744 1464route_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;
fee6e4e4 1479 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
718e3744 1480 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. */
94f2b392 1506static void *
fd79ac91 1507route_set_community_delete_compile (const char *arg)
718e3744 1508{
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. */
94f2b392 1527static void
718e3744 1528route_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\f
1542/* `set extcommunity rt COMMUNITY' */
1543
1544/* For community set mechanism. */
94f2b392 1545static route_map_result_t
718e3744 1546route_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. */
fb982c25 1563 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
718e3744 1564
1565 if (old_ecom)
1566 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1567 else
1568 new_ecom = ecommunity_dup (ecom);
1569
fb982c25 1570 bgp_info->attr->extra->ecommunity = new_ecom;
718e3744 1571
70601e06 1572 if (old_ecom)
1573 ecommunity_free (old_ecom);
1574
718e3744 1575 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1576 }
1577 return RMAP_OKAY;
1578}
1579
1580/* Compile function for set community. */
94f2b392 1581static void *
fd79ac91 1582route_set_ecommunity_rt_compile (const char *arg)
718e3744 1583{
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. */
94f2b392 1593static void
718e3744 1594route_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. */
94f2b392 1612static route_map_result_t
718e3744 1613route_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);
fb982c25 1628 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
718e3744 1629 }
1630 return RMAP_OKAY;
1631}
1632
1633/* Compile function for set community. */
94f2b392 1634static void *
fd79ac91 1635route_set_ecommunity_soo_compile (const char *arg)
718e3744 1636{
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. */
94f2b392 1647static void
718e3744 1648route_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\f
1663/* `set origin ORIGIN' */
1664
1665/* For origin set. */
94f2b392 1666static route_map_result_t
718e3744 1667route_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. */
94f2b392 1684static void *
fd79ac91 1685route_set_origin_compile (const char *arg)
718e3744 1686{
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. */
94f2b392 1702static void
718e3744 1703route_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\f
1717/* `set atomic-aggregate' */
1718
1719/* For atomic aggregate set. */
94f2b392 1720static route_map_result_t
718e3744 1721route_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. */
94f2b392 1736static void *
fd79ac91 1737route_set_atomic_aggregate_compile (const char *arg)
718e3744 1738{
1739 return (void *)1;
1740}
1741
1742/* Compile function for atomic aggregate. */
94f2b392 1743static void
718e3744 1744route_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\f
1758/* `set aggregator as AS A.B.C.D' */
1759struct aggregator
1760{
1761 as_t as;
1762 struct in_addr address;
1763};
1764
94f2b392 1765static route_map_result_t
718e3744 1766route_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;
fb982c25 1771 struct attr_extra *ae;
718e3744 1772
1773 if (type == RMAP_BGP)
1774 {
1775 bgp_info = object;
1776 aggregator = rule;
fb982c25
PJ
1777 ae = bgp_attr_extra_get (bgp_info->attr);
1778
1779 ae->aggregator_as = aggregator->as;
1780 ae->aggregator_addr = aggregator->address;
718e3744 1781 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1782 }
1783
1784 return RMAP_OKAY;
1785}
1786
94f2b392 1787static void *
fd79ac91 1788route_set_aggregator_as_compile (const char *arg)
718e3744 1789{
1790 struct aggregator *aggregator;
1791 char as[10];
1792 char address[20];
1793
393deb9b 1794 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
718e3744 1795 sscanf (arg, "%s %s", as, address);
1796
1797 aggregator->as = strtoul (as, NULL, 10);
1798 inet_aton (address, &aggregator->address);
1799
1800 return aggregator;
1801}
1802
94f2b392 1803static void
718e3744 1804route_set_aggregator_as_free (void *rule)
1805{
1806 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1807}
1808
1809struct route_map_rule_cmd route_set_aggregator_as_cmd =
1810{
1811 "aggregator as",
1812 route_set_aggregator_as,
1813 route_set_aggregator_as_compile,
1814 route_set_aggregator_as_free,
1815};
1816\f
1817#ifdef HAVE_IPV6
1818/* `match ipv6 address IP_ACCESS_LIST' */
1819
94f2b392 1820static route_map_result_t
718e3744 1821route_match_ipv6_address (void *rule, struct prefix *prefix,
1822 route_map_object_t type, void *object)
1823{
1824 struct access_list *alist;
1825
1826 if (type == RMAP_BGP)
1827 {
1828 alist = access_list_lookup (AFI_IP6, (char *) rule);
1829 if (alist == NULL)
1830 return RMAP_NOMATCH;
1831
1832 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1833 RMAP_NOMATCH : RMAP_MATCH);
1834 }
1835 return RMAP_NOMATCH;
1836}
1837
94f2b392 1838static void *
fd79ac91 1839route_match_ipv6_address_compile (const char *arg)
718e3744 1840{
1841 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1842}
1843
94f2b392 1844static void
718e3744 1845route_match_ipv6_address_free (void *rule)
1846{
1847 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1848}
1849
1850/* Route map commands for ip address matching. */
1851struct route_map_rule_cmd route_match_ipv6_address_cmd =
1852{
1853 "ipv6 address",
1854 route_match_ipv6_address,
1855 route_match_ipv6_address_compile,
1856 route_match_ipv6_address_free
1857};
1858\f
1859/* `match ipv6 next-hop IP_ADDRESS' */
1860
94f2b392 1861static route_map_result_t
718e3744 1862route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1863 route_map_object_t type, void *object)
1864{
1865 struct in6_addr *addr;
1866 struct bgp_info *bgp_info;
1867
1868 if (type == RMAP_BGP)
1869 {
1870 addr = rule;
1871 bgp_info = object;
fb982c25
PJ
1872
1873 if (!bgp_info->attr->extra)
1874 return RMAP_NOMATCH;
1875
1876 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
718e3744 1877 return RMAP_MATCH;
1878
fb982c25
PJ
1879 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1880 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
718e3744 1881 return RMAP_MATCH;
1882
1883 return RMAP_NOMATCH;
1884 }
1885
1886 return RMAP_NOMATCH;
1887}
1888
94f2b392 1889static void *
fd79ac91 1890route_match_ipv6_next_hop_compile (const char *arg)
718e3744 1891{
1892 struct in6_addr *address;
1893 int ret;
1894
1895 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1896
1897 ret = inet_pton (AF_INET6, arg, address);
1898 if (!ret)
1899 {
1900 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1901 return NULL;
1902 }
1903
1904 return address;
1905}
1906
94f2b392 1907static void
718e3744 1908route_match_ipv6_next_hop_free (void *rule)
1909{
1910 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1911}
1912
1913struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1914{
1915 "ipv6 next-hop",
1916 route_match_ipv6_next_hop,
1917 route_match_ipv6_next_hop_compile,
1918 route_match_ipv6_next_hop_free
1919};
1920\f
1921/* `match ipv6 address prefix-list PREFIX_LIST' */
1922
94f2b392 1923static route_map_result_t
718e3744 1924route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1925 route_map_object_t type, void *object)
1926{
1927 struct prefix_list *plist;
1928
1929 if (type == RMAP_BGP)
1930 {
1931 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1932 if (plist == NULL)
1933 return RMAP_NOMATCH;
1934
1935 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1936 RMAP_NOMATCH : RMAP_MATCH);
1937 }
1938 return RMAP_NOMATCH;
1939}
1940
94f2b392 1941static void *
fd79ac91 1942route_match_ipv6_address_prefix_list_compile (const char *arg)
718e3744 1943{
1944 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1945}
1946
94f2b392 1947static void
718e3744 1948route_match_ipv6_address_prefix_list_free (void *rule)
1949{
1950 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1951}
1952
1953struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1954{
1955 "ipv6 address prefix-list",
1956 route_match_ipv6_address_prefix_list,
1957 route_match_ipv6_address_prefix_list_compile,
1958 route_match_ipv6_address_prefix_list_free
1959};
1960\f
1961/* `set ipv6 nexthop global IP_ADDRESS' */
1962
1963/* Set nexthop to object. ojbect must be pointer to struct attr. */
94f2b392 1964static route_map_result_t
718e3744 1965route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1966 route_map_object_t type, void *object)
1967{
1968 struct in6_addr *address;
1969 struct bgp_info *bgp_info;
1970
1971 if (type == RMAP_BGP)
1972 {
1973 /* Fetch routemap's rule information. */
1974 address = rule;
1975 bgp_info = object;
1976
1977 /* Set next hop value. */
fb982c25 1978 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
718e3744 1979
1980 /* Set nexthop length. */
fb982c25
PJ
1981 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1982 bgp_info->attr->extra->mp_nexthop_len = 16;
718e3744 1983 }
1984
1985 return RMAP_OKAY;
1986}
1987
1988/* Route map `ip next-hop' compile function. Given string is converted
1989 to struct in_addr structure. */
94f2b392 1990static void *
fd79ac91 1991route_set_ipv6_nexthop_global_compile (const char *arg)
718e3744 1992{
1993 int ret;
1994 struct in6_addr *address;
1995
1996 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1997
1998 ret = inet_pton (AF_INET6, arg, address);
1999
2000 if (ret == 0)
2001 {
2002 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2003 return NULL;
2004 }
2005
2006 return address;
2007}
2008
2009/* Free route map's compiled `ip next-hop' value. */
94f2b392 2010static void
718e3744 2011route_set_ipv6_nexthop_global_free (void *rule)
2012{
2013 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2014}
2015
2016/* Route map commands for ip nexthop set. */
2017struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2018{
2019 "ipv6 next-hop global",
2020 route_set_ipv6_nexthop_global,
2021 route_set_ipv6_nexthop_global_compile,
2022 route_set_ipv6_nexthop_global_free
2023};
2024\f
2025/* `set ipv6 nexthop local IP_ADDRESS' */
2026
2027/* Set nexthop to object. ojbect must be pointer to struct attr. */
94f2b392 2028static route_map_result_t
718e3744 2029route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2030 route_map_object_t type, void *object)
2031{
2032 struct in6_addr *address;
2033 struct bgp_info *bgp_info;
2034
2035 if (type == RMAP_BGP)
2036 {
2037 /* Fetch routemap's rule information. */
2038 address = rule;
2039 bgp_info = object;
2040
2041 /* Set next hop value. */
fb982c25 2042 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
718e3744 2043
2044 /* Set nexthop length. */
fb982c25
PJ
2045 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2046 bgp_info->attr->extra->mp_nexthop_len = 32;
718e3744 2047 }
2048
2049 return RMAP_OKAY;
2050}
2051
2052/* Route map `ip nexthop' compile function. Given string is converted
2053 to struct in_addr structure. */
94f2b392 2054static void *
fd79ac91 2055route_set_ipv6_nexthop_local_compile (const char *arg)
718e3744 2056{
2057 int ret;
2058 struct in6_addr *address;
2059
2060 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2061
2062 ret = inet_pton (AF_INET6, arg, address);
2063
2064 if (ret == 0)
2065 {
2066 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2067 return NULL;
2068 }
2069
2070 return address;
2071}
2072
2073/* Free route map's compiled `ip nexthop' value. */
94f2b392 2074static void
718e3744 2075route_set_ipv6_nexthop_local_free (void *rule)
2076{
2077 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2078}
2079
2080/* Route map commands for ip nexthop set. */
2081struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2082{
2083 "ipv6 next-hop local",
2084 route_set_ipv6_nexthop_local,
2085 route_set_ipv6_nexthop_local_compile,
2086 route_set_ipv6_nexthop_local_free
2087};
2088#endif /* HAVE_IPV6 */
2089\f
2090/* `set vpnv4 nexthop A.B.C.D' */
2091
94f2b392 2092static route_map_result_t
718e3744 2093route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2094 route_map_object_t type, void *object)
2095{
2096 struct in_addr *address;
2097 struct bgp_info *bgp_info;
2098
2099 if (type == RMAP_BGP)
2100 {
2101 /* Fetch routemap's rule information. */
2102 address = rule;
2103 bgp_info = object;
2104
2105 /* Set next hop value. */
fb982c25 2106 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
718e3744 2107 }
2108
2109 return RMAP_OKAY;
2110}
2111
94f2b392 2112static void *
fd79ac91 2113route_set_vpnv4_nexthop_compile (const char *arg)
718e3744 2114{
2115 int ret;
2116 struct in_addr *address;
2117
2118 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2119
2120 ret = inet_aton (arg, address);
2121
2122 if (ret == 0)
2123 {
2124 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2125 return NULL;
2126 }
2127
2128 return address;
2129}
2130
94f2b392 2131static void
718e3744 2132route_set_vpnv4_nexthop_free (void *rule)
2133{
2134 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2135}
2136
2137/* Route map commands for ip nexthop set. */
2138struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2139{
2140 "vpnv4 next-hop",
2141 route_set_vpnv4_nexthop,
2142 route_set_vpnv4_nexthop_compile,
2143 route_set_vpnv4_nexthop_free
2144};
2145\f
2146/* `set originator-id' */
2147
2148/* For origin set. */
94f2b392 2149static route_map_result_t
718e3744 2150route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2151{
2152 struct in_addr *address;
2153 struct bgp_info *bgp_info;
2154
2155 if (type == RMAP_BGP)
2156 {
2157 address = rule;
2158 bgp_info = object;
2159
2160 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
fb982c25 2161 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
718e3744 2162 }
2163
2164 return RMAP_OKAY;
2165}
2166
2167/* Compile function for originator-id set. */
94f2b392 2168static void *
fd79ac91 2169route_set_originator_id_compile (const char *arg)
718e3744 2170{
2171 int ret;
2172 struct in_addr *address;
2173
2174 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2175
2176 ret = inet_aton (arg, address);
2177
2178 if (ret == 0)
2179 {
2180 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2181 return NULL;
2182 }
2183
2184 return address;
2185}
2186
2187/* Compile function for originator_id set. */
94f2b392 2188static void
718e3744 2189route_set_originator_id_free (void *rule)
2190{
2191 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2192}
2193
2194/* Set metric rule structure. */
2195struct route_map_rule_cmd route_set_originator_id_cmd =
2196{
2197 "originator-id",
2198 route_set_originator_id,
2199 route_set_originator_id_compile,
2200 route_set_originator_id_free,
2201};
2202\f
2203/* Add bgp route map rule. */
94f2b392 2204static int
718e3744 2205bgp_route_match_add (struct vty *vty, struct route_map_index *index,
fd79ac91 2206 const char *command, const char *arg)
718e3744 2207{
2208 int ret;
2209
2210 ret = route_map_add_match (index, command, arg);
2211 if (ret)
2212 {
2213 switch (ret)
2214 {
2215 case RMAP_RULE_MISSING:
2216 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2217 return CMD_WARNING;
718e3744 2218 case RMAP_COMPILE_ERROR:
2219 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2220 return CMD_WARNING;
718e3744 2221 }
2222 }
2223 return CMD_SUCCESS;
2224}
2225
2226/* Delete bgp route map rule. */
94f2b392 2227static int
718e3744 2228bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
fd79ac91 2229 const char *command, const char *arg)
718e3744 2230{
2231 int ret;
2232
2233 ret = route_map_delete_match (index, command, arg);
2234 if (ret)
2235 {
2236 switch (ret)
2237 {
2238 case RMAP_RULE_MISSING:
2239 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2240 return CMD_WARNING;
718e3744 2241 case RMAP_COMPILE_ERROR:
2242 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2243 return CMD_WARNING;
718e3744 2244 }
2245 }
2246 return CMD_SUCCESS;
2247}
2248
2249/* Add bgp route map rule. */
94f2b392 2250static int
718e3744 2251bgp_route_set_add (struct vty *vty, struct route_map_index *index,
fd79ac91 2252 const char *command, const char *arg)
718e3744 2253{
2254 int ret;
2255
2256 ret = route_map_add_set (index, command, arg);
2257 if (ret)
2258 {
2259 switch (ret)
2260 {
2261 case RMAP_RULE_MISSING:
2262 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2263 return CMD_WARNING;
718e3744 2264 case RMAP_COMPILE_ERROR:
2265 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2266 return CMD_WARNING;
718e3744 2267 }
2268 }
2269 return CMD_SUCCESS;
2270}
2271
2272/* Delete bgp route map rule. */
94f2b392 2273static int
718e3744 2274bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
fd79ac91 2275 const char *command, const char *arg)
718e3744 2276{
2277 int ret;
2278
2279 ret = route_map_delete_set (index, command, arg);
2280 if (ret)
2281 {
2282 switch (ret)
2283 {
2284 case RMAP_RULE_MISSING:
2285 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2286 return CMD_WARNING;
718e3744 2287 case RMAP_COMPILE_ERROR:
2288 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2289 return CMD_WARNING;
718e3744 2290 }
2291 }
2292 return CMD_SUCCESS;
2293}
2294
2295/* Hook function for updating route_map assignment. */
94f2b392 2296static void
fd79ac91 2297bgp_route_map_update (const char *unused)
718e3744 2298{
2299 int i;
2300 afi_t afi;
2301 safi_t safi;
2302 int direct;
1eb8ef25 2303 struct listnode *node, *nnode;
2304 struct listnode *mnode, *mnnode;
718e3744 2305 struct bgp *bgp;
2306 struct peer *peer;
2307 struct peer_group *group;
2308 struct bgp_filter *filter;
2309 struct bgp_node *bn;
2310 struct bgp_static *bgp_static;
2311
2312 /* For neighbor route-map updates. */
1eb8ef25 2313 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 2314 {
1eb8ef25 2315 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 2316 {
2317 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2318 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2319 {
2320 filter = &peer->filter[afi][safi];
2321
fee0f4c6 2322 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
718e3744 2323 {
2324 if (filter->map[direct].name)
2325 filter->map[direct].map =
2326 route_map_lookup_by_name (filter->map[direct].name);
2327 else
2328 filter->map[direct].map = NULL;
2329 }
2330
2331 if (filter->usmap.name)
2332 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2333 else
2334 filter->usmap.map = NULL;
2335 }
2336 }
1eb8ef25 2337 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
718e3744 2338 {
2339 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2340 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2341 {
2342 filter = &group->conf->filter[afi][safi];
2343
fee0f4c6 2344 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
718e3744 2345 {
2346 if (filter->map[direct].name)
2347 filter->map[direct].map =
2348 route_map_lookup_by_name (filter->map[direct].name);
2349 else
2350 filter->map[direct].map = NULL;
2351 }
2352
2353 if (filter->usmap.name)
2354 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2355 else
2356 filter->usmap.map = NULL;
2357 }
2358 }
2359 }
2360
2361 /* For default-originate route-map updates. */
1eb8ef25 2362 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 2363 {
1eb8ef25 2364 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 2365 {
2366 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2367 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2368 {
2369 if (peer->default_rmap[afi][safi].name)
2370 peer->default_rmap[afi][safi].map =
2371 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2372 else
2373 peer->default_rmap[afi][safi].map = NULL;
2374 }
2375 }
2376 }
2377
2378 /* For network route-map updates. */
1eb8ef25 2379 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 2380 {
2381 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2382 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2383 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2384 bn = bgp_route_next (bn))
2385 if ((bgp_static = bn->info) != NULL)
2386 {
2387 if (bgp_static->rmap.name)
2388 bgp_static->rmap.map =
2389 route_map_lookup_by_name (bgp_static->rmap.name);
2390 else
2391 bgp_static->rmap.map = NULL;
2392 }
2393 }
2394
2395 /* For redistribute route-map updates. */
1eb8ef25 2396 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 2397 {
2398 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2399 {
2400 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2401 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2402 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2403#ifdef HAVE_IPV6
2404 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2405 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2406 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2407#endif /* HAVE_IPV6 */
2408 }
2409 }
2410}
2411\f
fee0f4c6 2412DEFUN (match_peer,
2413 match_peer_cmd,
2414 "match peer (A.B.C.D|X:X::X:X)",
2415 MATCH_STR
2416 "Match peer address\n"
2417 "IPv6 address of peer\n"
2418 "IP address of peer\n")
2419{
2420 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2421}
2422
2423DEFUN (match_peer_local,
2424 match_peer_local_cmd,
2425 "match peer local",
2426 MATCH_STR
2427 "Match peer address\n"
2428 "Static or Redistributed routes\n")
2429{
2430 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2431}
2432
2433DEFUN (no_match_peer,
2434 no_match_peer_cmd,
2435 "no match peer",
2436 NO_STR
2437 MATCH_STR
2438 "Match peer address\n")
2439{
2440 if (argc == 0)
2441 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2442
2443 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2444}
2445
2446ALIAS (no_match_peer,
2447 no_match_peer_val_cmd,
2448 "no match peer (A.B.C.D|X:X::X:X)",
2449 NO_STR
2450 MATCH_STR
2451 "Match peer address\n"
2452 "IPv6 address of peer\n"
2453 "IP address of peer\n")
2454
2455ALIAS (no_match_peer,
2456 no_match_peer_local_cmd,
2457 "no match peer local",
2458 NO_STR
2459 MATCH_STR
2460 "Match peer address\n"
2461 "Static or Redistributed routes\n")
2462
718e3744 2463DEFUN (match_ip_address,
2464 match_ip_address_cmd,
2465 "match ip address (<1-199>|<1300-2699>|WORD)",
2466 MATCH_STR
2467 IP_STR
2468 "Match address of route\n"
2469 "IP access-list number\n"
2470 "IP access-list number (expanded range)\n"
2471 "IP Access-list name\n")
2472{
2473 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2474}
2475
2476DEFUN (no_match_ip_address,
2477 no_match_ip_address_cmd,
2478 "no match ip address",
2479 NO_STR
2480 MATCH_STR
2481 IP_STR
2482 "Match address of route\n")
2483{
2484 if (argc == 0)
2485 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2486
2487 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2488}
2489
2490ALIAS (no_match_ip_address,
2491 no_match_ip_address_val_cmd,
2492 "no match ip address (<1-199>|<1300-2699>|WORD)",
2493 NO_STR
2494 MATCH_STR
2495 IP_STR
2496 "Match address of route\n"
2497 "IP access-list number\n"
2498 "IP access-list number (expanded range)\n"
2499 "IP Access-list name\n")
2500
2501DEFUN (match_ip_next_hop,
2502 match_ip_next_hop_cmd,
2503 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2504 MATCH_STR
2505 IP_STR
2506 "Match next-hop address of route\n"
2507 "IP access-list number\n"
2508 "IP access-list number (expanded range)\n"
2509 "IP Access-list name\n")
2510{
2511 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2512}
2513
2514DEFUN (no_match_ip_next_hop,
2515 no_match_ip_next_hop_cmd,
2516 "no match ip next-hop",
2517 NO_STR
2518 MATCH_STR
2519 IP_STR
2520 "Match next-hop address of route\n")
2521{
2522 if (argc == 0)
2523 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2524
2525 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2526}
2527
2528ALIAS (no_match_ip_next_hop,
2529 no_match_ip_next_hop_val_cmd,
2530 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2531 NO_STR
2532 MATCH_STR
2533 IP_STR
2534 "Match next-hop address of route\n"
2535 "IP access-list number\n"
2536 "IP access-list number (expanded range)\n"
2537 "IP Access-list name\n")
2538
c1643bb7 2539DEFUN (match_ip_route_source,
2540 match_ip_route_source_cmd,
2541 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2542 MATCH_STR
2543 IP_STR
2544 "Match advertising source address of route\n"
2545 "IP access-list number\n"
2546 "IP access-list number (expanded range)\n"
2547 "IP standard access-list name\n")
2548{
2549 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2550}
2551
2552DEFUN (no_match_ip_route_source,
2553 no_match_ip_route_source_cmd,
2554 "no match ip route-source",
2555 NO_STR
2556 MATCH_STR
2557 IP_STR
2558 "Match advertising source address of route\n")
2559{
2560 if (argc == 0)
2561 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2562
2563 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2564}
2565
2566ALIAS (no_match_ip_route_source,
2567 no_match_ip_route_source_val_cmd,
2568 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2569 NO_STR
2570 MATCH_STR
2571 IP_STR
2572 "Match advertising source address of route\n"
2573 "IP access-list number\n"
2574 "IP access-list number (expanded range)\n"
30a2231a 2575 "IP standard access-list name\n")
c1643bb7 2576
718e3744 2577DEFUN (match_ip_address_prefix_list,
2578 match_ip_address_prefix_list_cmd,
2579 "match ip address prefix-list WORD",
2580 MATCH_STR
2581 IP_STR
2582 "Match address of route\n"
2583 "Match entries of prefix-lists\n"
2584 "IP prefix-list name\n")
2585{
2586 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2587}
2588
2589DEFUN (no_match_ip_address_prefix_list,
2590 no_match_ip_address_prefix_list_cmd,
2591 "no match ip address prefix-list",
2592 NO_STR
2593 MATCH_STR
2594 IP_STR
2595 "Match address of route\n"
2596 "Match entries of prefix-lists\n")
2597{
2598 if (argc == 0)
2599 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2600
2601 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2602}
2603
2604ALIAS (no_match_ip_address_prefix_list,
2605 no_match_ip_address_prefix_list_val_cmd,
2606 "no match ip address prefix-list WORD",
2607 NO_STR
2608 MATCH_STR
2609 IP_STR
2610 "Match address of route\n"
2611 "Match entries of prefix-lists\n"
2612 "IP prefix-list name\n")
2613
2614DEFUN (match_ip_next_hop_prefix_list,
2615 match_ip_next_hop_prefix_list_cmd,
2616 "match ip next-hop prefix-list WORD",
2617 MATCH_STR
2618 IP_STR
2619 "Match next-hop address of route\n"
2620 "Match entries of prefix-lists\n"
2621 "IP prefix-list name\n")
2622{
2623 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2624}
2625
2626DEFUN (no_match_ip_next_hop_prefix_list,
2627 no_match_ip_next_hop_prefix_list_cmd,
2628 "no match ip next-hop prefix-list",
2629 NO_STR
2630 MATCH_STR
2631 IP_STR
2632 "Match next-hop address of route\n"
2633 "Match entries of prefix-lists\n")
2634{
2635 if (argc == 0)
2636 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2637
2638 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2639}
2640
2641ALIAS (no_match_ip_next_hop_prefix_list,
2642 no_match_ip_next_hop_prefix_list_val_cmd,
2643 "no match ip next-hop prefix-list WORD",
2644 NO_STR
2645 MATCH_STR
2646 IP_STR
2647 "Match next-hop address of route\n"
2648 "Match entries of prefix-lists\n"
2649 "IP prefix-list name\n")
2650
c1643bb7 2651DEFUN (match_ip_route_source_prefix_list,
2652 match_ip_route_source_prefix_list_cmd,
2653 "match ip route-source prefix-list WORD",
2654 MATCH_STR
2655 IP_STR
2656 "Match advertising source address of route\n"
2657 "Match entries of prefix-lists\n"
2658 "IP prefix-list name\n")
2659{
2660 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2661}
2662
2663DEFUN (no_match_ip_route_source_prefix_list,
2664 no_match_ip_route_source_prefix_list_cmd,
2665 "no match ip route-source prefix-list",
2666 NO_STR
2667 MATCH_STR
2668 IP_STR
2669 "Match advertising source address of route\n"
2670 "Match entries of prefix-lists\n")
2671{
2672 if (argc == 0)
2673 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2674
2675 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2676}
2677
2678ALIAS (no_match_ip_route_source_prefix_list,
2679 no_match_ip_route_source_prefix_list_val_cmd,
2680 "no match ip route-source prefix-list WORD",
2681 NO_STR
2682 MATCH_STR
2683 IP_STR
2684 "Match advertising source address of route\n"
2685 "Match entries of prefix-lists\n"
30a2231a 2686 "IP prefix-list name\n")
c1643bb7 2687
718e3744 2688DEFUN (match_metric,
2689 match_metric_cmd,
2690 "match metric <0-4294967295>",
2691 MATCH_STR
2692 "Match metric of route\n"
2693 "Metric value\n")
2694{
2695 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2696}
2697
2698DEFUN (no_match_metric,
2699 no_match_metric_cmd,
2700 "no match metric",
2701 NO_STR
2702 MATCH_STR
2703 "Match metric of route\n")
2704{
2705 if (argc == 0)
2706 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2707
2708 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2709}
2710
2711ALIAS (no_match_metric,
2712 no_match_metric_val_cmd,
2713 "no match metric <0-4294967295>",
2714 NO_STR
2715 MATCH_STR
2716 "Match metric of route\n"
2717 "Metric value\n")
2718
2719DEFUN (match_community,
2720 match_community_cmd,
fee6e4e4 2721 "match community (<1-99>|<100-500>|WORD)",
718e3744 2722 MATCH_STR
2723 "Match BGP community list\n"
2724 "Community-list number (standard)\n"
2725 "Community-list number (expanded)\n"
2726 "Community-list name\n")
2727{
2728 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2729}
2730
2731DEFUN (match_community_exact,
2732 match_community_exact_cmd,
fee6e4e4 2733 "match community (<1-99>|<100-500>|WORD) exact-match",
718e3744 2734 MATCH_STR
2735 "Match BGP community list\n"
2736 "Community-list number (standard)\n"
2737 "Community-list number (expanded)\n"
2738 "Community-list name\n"
2739 "Do exact matching of communities\n")
2740{
2741 int ret;
2742 char *argstr;
2743
2744 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2745 strlen (argv[0]) + strlen ("exact-match") + 2);
2746
2747 sprintf (argstr, "%s exact-match", argv[0]);
2748
2749 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2750
2751 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2752
2753 return ret;
2754}
2755
2756DEFUN (no_match_community,
2757 no_match_community_cmd,
2758 "no match community",
2759 NO_STR
2760 MATCH_STR
2761 "Match BGP community list\n")
2762{
2763 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2764}
2765
2766ALIAS (no_match_community,
2767 no_match_community_val_cmd,
fee6e4e4 2768 "no match community (<1-99>|<100-500>|WORD)",
718e3744 2769 NO_STR
2770 MATCH_STR
2771 "Match BGP community list\n"
2772 "Community-list number (standard)\n"
2773 "Community-list number (expanded)\n"
2774 "Community-list name\n")
2775
2776ALIAS (no_match_community,
2777 no_match_community_exact_cmd,
fee6e4e4 2778 "no match community (<1-99>|<100-500>|WORD) exact-match",
718e3744 2779 NO_STR
2780 MATCH_STR
2781 "Match BGP community list\n"
2782 "Community-list number (standard)\n"
2783 "Community-list number (expanded)\n"
2784 "Community-list name\n"
2785 "Do exact matching of communities\n")
2786
73ffb25b 2787DEFUN (match_ecommunity,
2788 match_ecommunity_cmd,
fee6e4e4 2789 "match extcommunity (<1-99>|<100-500>|WORD)",
73ffb25b 2790 MATCH_STR
2791 "Match BGP/VPN extended community list\n"
2792 "Extended community-list number (standard)\n"
2793 "Extended community-list number (expanded)\n"
2794 "Extended community-list name\n")
2795{
2796 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2797}
2798
2799DEFUN (no_match_ecommunity,
2800 no_match_ecommunity_cmd,
2801 "no match extcommunity",
2802 NO_STR
2803 MATCH_STR
2804 "Match BGP/VPN extended community list\n")
2805{
2806 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2807}
2808
2809ALIAS (no_match_ecommunity,
2810 no_match_ecommunity_val_cmd,
fee6e4e4 2811 "no match extcommunity (<1-99>|<100-500>|WORD)",
73ffb25b 2812 NO_STR
2813 MATCH_STR
2814 "Match BGP/VPN extended community list\n"
2815 "Extended community-list number (standard)\n"
2816 "Extended community-list number (expanded)\n"
2817 "Extended community-list name\n")
2818
718e3744 2819DEFUN (match_aspath,
2820 match_aspath_cmd,
2821 "match as-path WORD",
2822 MATCH_STR
2823 "Match BGP AS path list\n"
2824 "AS path access-list name\n")
2825{
2826 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2827}
2828
2829DEFUN (no_match_aspath,
2830 no_match_aspath_cmd,
2831 "no match as-path",
2832 NO_STR
2833 MATCH_STR
2834 "Match BGP AS path list\n")
2835{
2836 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2837}
2838
2839ALIAS (no_match_aspath,
2840 no_match_aspath_val_cmd,
2841 "no match as-path WORD",
2842 NO_STR
2843 MATCH_STR
2844 "Match BGP AS path list\n"
2845 "AS path access-list name\n")
2846
2847DEFUN (match_origin,
2848 match_origin_cmd,
2849 "match origin (egp|igp|incomplete)",
2850 MATCH_STR
2851 "BGP origin code\n"
2852 "remote EGP\n"
2853 "local IGP\n"
2854 "unknown heritage\n")
2855{
2856 if (strncmp (argv[0], "igp", 2) == 0)
2857 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2858 if (strncmp (argv[0], "egp", 1) == 0)
2859 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2860 if (strncmp (argv[0], "incomplete", 2) == 0)
2861 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2862
2863 return CMD_WARNING;
2864}
2865
2866DEFUN (no_match_origin,
2867 no_match_origin_cmd,
2868 "no match origin",
2869 NO_STR
2870 MATCH_STR
2871 "BGP origin code\n")
2872{
2873 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2874}
2875
2876ALIAS (no_match_origin,
2877 no_match_origin_val_cmd,
2878 "no match origin (egp|igp|incomplete)",
2879 NO_STR
2880 MATCH_STR
2881 "BGP origin code\n"
2882 "remote EGP\n"
2883 "local IGP\n"
2884 "unknown heritage\n")
2885
2886DEFUN (set_ip_nexthop,
2887 set_ip_nexthop_cmd,
af5cd0a5 2888 "set ip next-hop A.B.C.D",
718e3744 2889 SET_STR
2890 IP_STR
2891 "Next hop address\n"
af5cd0a5 2892 "IP address of next hop\n")
718e3744 2893{
2894 union sockunion su;
2895 int ret;
2896
2897 ret = str2sockunion (argv[0], &su);
2898 if (ret < 0)
2899 {
2900 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2901 return CMD_WARNING;
2902 }
2903
2904 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2905}
2906
af5cd0a5 2907DEFUN (set_ip_nexthop_peer,
2908 set_ip_nexthop_peer_cmd,
2909 "set ip next-hop peer-address",
2910 SET_STR
2911 IP_STR
2912 "Next hop address\n"
2913 "Use peer address (for BGP only)\n")
2914{
2915 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2916}
2917
94f2b392 2918DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
af5cd0a5 2919 no_set_ip_nexthop_peer_cmd,
2920 "no set ip next-hop peer-address",
2921 NO_STR
2922 SET_STR
2923 IP_STR
2924 "Next hop address\n"
2925 "Use peer address (for BGP only)\n")
2926{
2927 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2928}
2929
2930
718e3744 2931DEFUN (no_set_ip_nexthop,
2932 no_set_ip_nexthop_cmd,
2933 "no set ip next-hop",
2934 NO_STR
2935 SET_STR
718e3744 2936 "Next hop address\n")
2937{
af5cd0a5 2938 if (argc == 0)
718e3744 2939 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2940
2941 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2942}
2943
2944ALIAS (no_set_ip_nexthop,
2945 no_set_ip_nexthop_val_cmd,
af5cd0a5 2946 "no set ip next-hop A.B.C.D",
718e3744 2947 NO_STR
2948 SET_STR
2949 IP_STR
2950 "Next hop address\n"
af5cd0a5 2951 "IP address of next hop\n")
718e3744 2952
2953DEFUN (set_metric,
2954 set_metric_cmd,
73ffb25b 2955 "set metric <0-4294967295>",
718e3744 2956 SET_STR
2957 "Metric value for destination routing protocol\n"
73ffb25b 2958 "Metric value\n")
718e3744 2959{
2960 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2961}
2962
73ffb25b 2963ALIAS (set_metric,
2964 set_metric_addsub_cmd,
2965 "set metric <+/-metric>",
2966 SET_STR
2967 "Metric value for destination routing protocol\n"
033e8612 2968 "Add or subtract metric\n")
73ffb25b 2969
718e3744 2970DEFUN (no_set_metric,
2971 no_set_metric_cmd,
2972 "no set metric",
2973 NO_STR
2974 SET_STR
2975 "Metric value for destination routing protocol\n")
2976{
2977 if (argc == 0)
2978 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2979
2980 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2981}
2982
2983ALIAS (no_set_metric,
2984 no_set_metric_val_cmd,
2985 "no set metric <0-4294967295>",
2986 NO_STR
2987 SET_STR
2988 "Metric value for destination routing protocol\n"
2989 "Metric value\n")
2990
2991DEFUN (set_local_pref,
2992 set_local_pref_cmd,
2993 "set local-preference <0-4294967295>",
2994 SET_STR
2995 "BGP local preference path attribute\n"
2996 "Preference value\n")
2997{
2998 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2999}
3000
3001DEFUN (no_set_local_pref,
3002 no_set_local_pref_cmd,
3003 "no set local-preference",
3004 NO_STR
3005 SET_STR
3006 "BGP local preference path attribute\n")
3007{
3008 if (argc == 0)
3009 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3010
3011 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3012}
3013
3014ALIAS (no_set_local_pref,
3015 no_set_local_pref_val_cmd,
3016 "no set local-preference <0-4294967295>",
3017 NO_STR
3018 SET_STR
3019 "BGP local preference path attribute\n"
3020 "Preference value\n")
3021
3022DEFUN (set_weight,
3023 set_weight_cmd,
3024 "set weight <0-4294967295>",
3025 SET_STR
3026 "BGP weight for routing table\n"
3027 "Weight value\n")
3028{
3029 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3030}
3031
3032DEFUN (no_set_weight,
3033 no_set_weight_cmd,
3034 "no set weight",
3035 NO_STR
3036 SET_STR
3037 "BGP weight for routing table\n")
3038{
3039 if (argc == 0)
3040 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3041
3042 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3043}
3044
3045ALIAS (no_set_weight,
3046 no_set_weight_val_cmd,
3047 "no set weight <0-4294967295>",
3048 NO_STR
3049 SET_STR
3050 "BGP weight for routing table\n"
3051 "Weight value\n")
3052
3053DEFUN (set_aspath_prepend,
3054 set_aspath_prepend_cmd,
10819ece 3055 "set as-path prepend ." CMD_AS_RANGE,
718e3744 3056 SET_STR
841f7a57 3057 "Transform BGP AS_PATH attribute\n"
718e3744 3058 "Prepend to the as-path\n"
3059 "AS number\n")
3060{
3061 int ret;
3062 char *str;
3063
3064 str = argv_concat (argv, argc, 0);
3065 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3066 XFREE (MTYPE_TMP, str);
3067
3068 return ret;
3069}
3070
3071DEFUN (no_set_aspath_prepend,
3072 no_set_aspath_prepend_cmd,
3073 "no set as-path prepend",
3074 NO_STR
3075 SET_STR
841f7a57 3076 "Transform BGP AS_PATH attribute\n"
718e3744 3077 "Prepend to the as-path\n")
3078{
a7f93f3e
DO
3079 int ret;
3080 char *str;
3081
3082 if (argc == 0)
3083 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3084
3085 str = argv_concat (argv, argc, 0);
3086 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3087 XFREE (MTYPE_TMP, str);
3088 return ret;
718e3744 3089}
3090
3091ALIAS (no_set_aspath_prepend,
3092 no_set_aspath_prepend_val_cmd,
10819ece 3093 "no set as-path prepend ." CMD_AS_RANGE,
718e3744 3094 NO_STR
3095 SET_STR
841f7a57 3096 "Transform BGP AS_PATH attribute\n"
718e3744 3097 "Prepend to the as-path\n"
3098 "AS number\n")
3099
841f7a57
DO
3100DEFUN (set_aspath_exclude,
3101 set_aspath_exclude_cmd,
10819ece 3102 "set as-path exclude ." CMD_AS_RANGE,
841f7a57
DO
3103 SET_STR
3104 "Transform BGP AS-path attribute\n"
3105 "Exclude from the as-path\n"
3106 "AS number\n")
3107{
3108 int ret;
3109 char *str;
3110
3111 str = argv_concat (argv, argc, 0);
3112 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3113 XFREE (MTYPE_TMP, str);
3114 return ret;
3115}
3116
3117DEFUN (no_set_aspath_exclude,
3118 no_set_aspath_exclude_cmd,
3119 "no set as-path exclude",
3120 NO_STR
3121 SET_STR
3122 "Transform BGP AS_PATH attribute\n"
3123 "Exclude from the as-path\n")
3124{
3125 int ret;
3126 char *str;
3127
3128 if (argc == 0)
3129 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3130
3131 str = argv_concat (argv, argc, 0);
3132 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3133 XFREE (MTYPE_TMP, str);
3134 return ret;
3135}
3136
3137ALIAS (no_set_aspath_exclude,
3138 no_set_aspath_exclude_val_cmd,
10819ece 3139 "no set as-path exclude ." CMD_AS_RANGE,
841f7a57
DO
3140 NO_STR
3141 SET_STR
3142 "Transform BGP AS_PATH attribute\n"
3143 "Exclude from the as-path\n"
3144 "AS number\n")
3145
718e3744 3146DEFUN (set_community,
3147 set_community_cmd,
3148 "set community .AA:NN",
3149 SET_STR
3150 "BGP community attribute\n"
3151 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3152{
3153 int i;
3154 int first = 0;
3155 int additive = 0;
3156 struct buffer *b;
3157 struct community *com = NULL;
3158 char *str;
3159 char *argstr;
3160 int ret;
3161
3162 b = buffer_new (1024);
3163
3164 for (i = 0; i < argc; i++)
3165 {
3166 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3167 {
3168 additive = 1;
3169 continue;
3170 }
3171
3172 if (first)
3173 buffer_putc (b, ' ');
3174 else
3175 first = 1;
3176
3177 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3178 {
3179 buffer_putstr (b, "internet");
3180 continue;
3181 }
3182 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3183 {
3184 buffer_putstr (b, "local-AS");
3185 continue;
3186 }
3187 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3188 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3189 {
3190 buffer_putstr (b, "no-advertise");
3191 continue;
3192 }
3193 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3194 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3195 {
3196 buffer_putstr (b, "no-export");
3197 continue;
3198 }
3199 buffer_putstr (b, argv[i]);
3200 }
3201 buffer_putc (b, '\0');
3202
3203 /* Fetch result string then compile it to communities attribute. */
3204 str = buffer_getstr (b);
3205 buffer_free (b);
3206
3207 if (str)
3208 {
3209 com = community_str2com (str);
3b8b1855 3210 XFREE (MTYPE_TMP, str);
718e3744 3211 }
3212
3213 /* Can't compile user input into communities attribute. */
3214 if (! com)
3215 {
3216 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3217 return CMD_WARNING;
3218 }
3219
3220 /* Set communites attribute string. */
3221 str = community_str (com);
3222
3223 if (additive)
3224 {
3225 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3226 strcpy (argstr, str);
3227 strcpy (argstr + strlen (str), " additive");
3228 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3229 XFREE (MTYPE_TMP, argstr);
3230 }
3231 else
3232 ret = bgp_route_set_add (vty, vty->index, "community", str);
3233
3234 community_free (com);
3235
3236 return ret;
3237}
3238
3239DEFUN (set_community_none,
3240 set_community_none_cmd,
3241 "set community none",
3242 SET_STR
3243 "BGP community attribute\n"
3244 "No community attribute\n")
3245{
3246 return bgp_route_set_add (vty, vty->index, "community", "none");
3247}
3248
3249DEFUN (no_set_community,
3250 no_set_community_cmd,
3251 "no set community",
3252 NO_STR
3253 SET_STR
3254 "BGP community attribute\n")
3255{
3256 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3257}
3258
3259ALIAS (no_set_community,
3260 no_set_community_val_cmd,
3261 "no set community .AA:NN",
3262 NO_STR
3263 SET_STR
3264 "BGP community attribute\n"
3265 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3266
3267ALIAS (no_set_community,
3268 no_set_community_none_cmd,
3269 "no set community none",
3270 NO_STR
3271 SET_STR
3272 "BGP community attribute\n"
3273 "No community attribute\n")
3274
3275DEFUN (set_community_delete,
3276 set_community_delete_cmd,
fee6e4e4 3277 "set comm-list (<1-99>|<100-500>|WORD) delete",
718e3744 3278 SET_STR
3279 "set BGP community list (for deletion)\n"
3280 "Community-list number (standard)\n"
3281 "Communitly-list number (expanded)\n"
3282 "Community-list name\n"
3283 "Delete matching communities\n")
3284{
3285 char *str;
3286
3287 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3288 strcpy (str, argv[0]);
3289 strcpy (str + strlen (argv[0]), " delete");
3290
3291 bgp_route_set_add (vty, vty->index, "comm-list", str);
3292
3293 XFREE (MTYPE_TMP, str);
3294 return CMD_SUCCESS;
3295}
3296
3297DEFUN (no_set_community_delete,
3298 no_set_community_delete_cmd,
3299 "no set comm-list",
3300 NO_STR
3301 SET_STR
3302 "set BGP community list (for deletion)\n")
3303{
3304 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3305}
3306
3307ALIAS (no_set_community_delete,
3308 no_set_community_delete_val_cmd,
fee6e4e4 3309 "no set comm-list (<1-99>|<100-500>|WORD) delete",
718e3744 3310 NO_STR
3311 SET_STR
3312 "set BGP community list (for deletion)\n"
3313 "Community-list number (standard)\n"
3314 "Communitly-list number (expanded)\n"
3315 "Community-list name\n"
3316 "Delete matching communities\n")
3317
3318DEFUN (set_ecommunity_rt,
3319 set_ecommunity_rt_cmd,
3320 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3321 SET_STR
3322 "BGP extended community attribute\n"
e6b6a564 3323 "Route Target extended community\n"
718e3744 3324 "VPN extended community\n")
3325{
3326 int ret;
3327 char *str;
3328
3329 str = argv_concat (argv, argc, 0);
3330 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3331 XFREE (MTYPE_TMP, str);
3332
3333 return ret;
3334}
3335
3336DEFUN (no_set_ecommunity_rt,
3337 no_set_ecommunity_rt_cmd,
3338 "no set extcommunity rt",
3339 NO_STR
3340 SET_STR
3341 "BGP extended community attribute\n"
e6b6a564 3342 "Route Target extended community\n")
718e3744 3343{
3344 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3345}
3346
3347ALIAS (no_set_ecommunity_rt,
3348 no_set_ecommunity_rt_val_cmd,
3349 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3350 NO_STR
3351 SET_STR
3352 "BGP extended community attribute\n"
e6b6a564 3353 "Route Target extended community\n"
718e3744 3354 "VPN extended community\n")
3355
3356DEFUN (set_ecommunity_soo,
3357 set_ecommunity_soo_cmd,
3358 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3359 SET_STR
3360 "BGP extended community attribute\n"
3361 "Site-of-Origin extended community\n"
3362 "VPN extended community\n")
3363{
3364 int ret;
3365 char *str;
3366
3367 str = argv_concat (argv, argc, 0);
3368 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3369 XFREE (MTYPE_TMP, str);
3370 return ret;
3371}
3372
3373DEFUN (no_set_ecommunity_soo,
3374 no_set_ecommunity_soo_cmd,
3375 "no set extcommunity soo",
3376 NO_STR
3377 SET_STR
3378 "BGP extended community attribute\n"
3379 "Site-of-Origin extended community\n")
3380{
3381 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3382}
3383
3384ALIAS (no_set_ecommunity_soo,
3385 no_set_ecommunity_soo_val_cmd,
3386 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3387 NO_STR
3388 SET_STR
3389 "BGP extended community attribute\n"
3390 "Site-of-Origin extended community\n"
3391 "VPN extended community\n")
3392
3393DEFUN (set_origin,
3394 set_origin_cmd,
3395 "set origin (egp|igp|incomplete)",
3396 SET_STR
3397 "BGP origin code\n"
3398 "remote EGP\n"
3399 "local IGP\n"
3400 "unknown heritage\n")
3401{
3402 if (strncmp (argv[0], "igp", 2) == 0)
3403 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3404 if (strncmp (argv[0], "egp", 1) == 0)
3405 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3406 if (strncmp (argv[0], "incomplete", 2) == 0)
3407 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3408
3409 return CMD_WARNING;
3410}
3411
3412DEFUN (no_set_origin,
3413 no_set_origin_cmd,
3414 "no set origin",
3415 NO_STR
3416 SET_STR
3417 "BGP origin code\n")
3418{
3419 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3420}
3421
3422ALIAS (no_set_origin,
3423 no_set_origin_val_cmd,
3424 "no set origin (egp|igp|incomplete)",
3425 NO_STR
3426 SET_STR
3427 "BGP origin code\n"
3428 "remote EGP\n"
3429 "local IGP\n"
3430 "unknown heritage\n")
3431
3432DEFUN (set_atomic_aggregate,
3433 set_atomic_aggregate_cmd,
3434 "set atomic-aggregate",
3435 SET_STR
3436 "BGP atomic aggregate attribute\n" )
3437{
3438 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3439}
3440
3441DEFUN (no_set_atomic_aggregate,
3442 no_set_atomic_aggregate_cmd,
3443 "no set atomic-aggregate",
3444 NO_STR
3445 SET_STR
3446 "BGP atomic aggregate attribute\n" )
3447{
3448 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3449}
3450
3451DEFUN (set_aggregator_as,
3452 set_aggregator_as_cmd,
320da874 3453 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
718e3744 3454 SET_STR
3455 "BGP aggregator attribute\n"
3456 "AS number of aggregator\n"
3457 "AS number\n"
3458 "IP address of aggregator\n")
3459{
3460 int ret;
3461 as_t as;
3462 struct in_addr address;
718e3744 3463 char *argstr;
3464
0b2aa3a0 3465 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
fd79ac91 3466
718e3744 3467 ret = inet_aton (argv[1], &address);
3468 if (ret == 0)
3469 {
3470 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3471 return CMD_WARNING;
3472 }
3473
3474 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3475 strlen (argv[0]) + strlen (argv[1]) + 2);
3476
3477 sprintf (argstr, "%s %s", argv[0], argv[1]);
3478
3479 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3480
3481 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3482
3483 return ret;
3484}
3485
3486DEFUN (no_set_aggregator_as,
3487 no_set_aggregator_as_cmd,
3488 "no set aggregator as",
3489 NO_STR
3490 SET_STR
3491 "BGP aggregator attribute\n"
3492 "AS number of aggregator\n")
3493{
3494 int ret;
3495 as_t as;
3496 struct in_addr address;
718e3744 3497 char *argstr;
3498
3499 if (argv == 0)
3500 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3501
0b2aa3a0 3502 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
718e3744 3503
3504 ret = inet_aton (argv[1], &address);
3505 if (ret == 0)
3506 {
3507 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3508 return CMD_WARNING;
3509 }
3510
3511 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3512 strlen (argv[0]) + strlen (argv[1]) + 2);
3513
3514 sprintf (argstr, "%s %s", argv[0], argv[1]);
3515
3516 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3517
3518 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3519
3520 return ret;
3521}
3522
3523ALIAS (no_set_aggregator_as,
3524 no_set_aggregator_as_val_cmd,
320da874 3525 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
718e3744 3526 NO_STR
3527 SET_STR
3528 "BGP aggregator attribute\n"
3529 "AS number of aggregator\n"
3530 "AS number\n"
3531 "IP address of aggregator\n")
3532
3533\f
3534#ifdef HAVE_IPV6
3535DEFUN (match_ipv6_address,
3536 match_ipv6_address_cmd,
3537 "match ipv6 address WORD",
3538 MATCH_STR
3539 IPV6_STR
3540 "Match IPv6 address of route\n"
3541 "IPv6 access-list name\n")
3542{
3543 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3544}
3545
3546DEFUN (no_match_ipv6_address,
3547 no_match_ipv6_address_cmd,
3548 "no match ipv6 address WORD",
3549 NO_STR
3550 MATCH_STR
3551 IPV6_STR
3552 "Match IPv6 address of route\n"
3553 "IPv6 access-list name\n")
3554{
3555 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3556}
3557
3558DEFUN (match_ipv6_next_hop,
3559 match_ipv6_next_hop_cmd,
3560 "match ipv6 next-hop X:X::X:X",
3561 MATCH_STR
3562 IPV6_STR
3563 "Match IPv6 next-hop address of route\n"
3564 "IPv6 address of next hop\n")
3565{
3566 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3567}
3568
3569DEFUN (no_match_ipv6_next_hop,
3570 no_match_ipv6_next_hop_cmd,
3571 "no match ipv6 next-hop X:X::X:X",
3572 NO_STR
3573 MATCH_STR
3574 IPV6_STR
3575 "Match IPv6 next-hop address of route\n"
3576 "IPv6 address of next hop\n")
3577{
3578 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3579}
3580
3581DEFUN (match_ipv6_address_prefix_list,
3582 match_ipv6_address_prefix_list_cmd,
3583 "match ipv6 address prefix-list WORD",
3584 MATCH_STR
3585 IPV6_STR
3586 "Match address of route\n"
3587 "Match entries of prefix-lists\n"
3588 "IP prefix-list name\n")
3589{
3590 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3591}
3592
3593DEFUN (no_match_ipv6_address_prefix_list,
3594 no_match_ipv6_address_prefix_list_cmd,
3595 "no match ipv6 address prefix-list WORD",
3596 NO_STR
3597 MATCH_STR
3598 IPV6_STR
3599 "Match address of route\n"
3600 "Match entries of prefix-lists\n"
3601 "IP prefix-list name\n")
3602{
3603 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3604}
3605
3606DEFUN (set_ipv6_nexthop_global,
3607 set_ipv6_nexthop_global_cmd,
3608 "set ipv6 next-hop global X:X::X:X",
3609 SET_STR
3610 IPV6_STR
3611 "IPv6 next-hop address\n"
3612 "IPv6 global address\n"
3613 "IPv6 address of next hop\n")
3614{
3615 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3616}
3617
3618DEFUN (no_set_ipv6_nexthop_global,
3619 no_set_ipv6_nexthop_global_cmd,
3620 "no set ipv6 next-hop global",
3621 NO_STR
3622 SET_STR
3623 IPV6_STR
3624 "IPv6 next-hop address\n"
3625 "IPv6 global address\n")
3626{
3627 if (argc == 0)
3628 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3629
3630 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3631}
3632
3633ALIAS (no_set_ipv6_nexthop_global,
3634 no_set_ipv6_nexthop_global_val_cmd,
3635 "no set ipv6 next-hop global X:X::X:X",
3636 NO_STR
3637 SET_STR
3638 IPV6_STR
3639 "IPv6 next-hop address\n"
3640 "IPv6 global address\n"
3641 "IPv6 address of next hop\n")
3642
3643DEFUN (set_ipv6_nexthop_local,
3644 set_ipv6_nexthop_local_cmd,
3645 "set ipv6 next-hop local X:X::X:X",
3646 SET_STR
3647 IPV6_STR
3648 "IPv6 next-hop address\n"
3649 "IPv6 local address\n"
3650 "IPv6 address of next hop\n")
3651{
3652 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3653}
3654
3655DEFUN (no_set_ipv6_nexthop_local,
3656 no_set_ipv6_nexthop_local_cmd,
3657 "no set ipv6 next-hop local",
3658 NO_STR
3659 SET_STR
3660 IPV6_STR
3661 "IPv6 next-hop address\n"
3662 "IPv6 local address\n")
3663{
3664 if (argc == 0)
3665 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3666
3667 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3668}
3669
3670ALIAS (no_set_ipv6_nexthop_local,
3671 no_set_ipv6_nexthop_local_val_cmd,
3672 "no set ipv6 next-hop local X:X::X:X",
3673 NO_STR
3674 SET_STR
3675 IPV6_STR
3676 "IPv6 next-hop address\n"
3677 "IPv6 local address\n"
3678 "IPv6 address of next hop\n")
3679#endif /* HAVE_IPV6 */
3680
3681DEFUN (set_vpnv4_nexthop,
3682 set_vpnv4_nexthop_cmd,
3683 "set vpnv4 next-hop A.B.C.D",
3684 SET_STR
3685 "VPNv4 information\n"
3686 "VPNv4 next-hop address\n"
3687 "IP address of next hop\n")
3688{
3689 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3690}
3691
3692DEFUN (no_set_vpnv4_nexthop,
3693 no_set_vpnv4_nexthop_cmd,
3694 "no set vpnv4 next-hop",
3695 NO_STR
3696 SET_STR
3697 "VPNv4 information\n"
3698 "VPNv4 next-hop address\n")
3699{
3700 if (argc == 0)
3701 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3702
3703 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3704}
3705
3706ALIAS (no_set_vpnv4_nexthop,
3707 no_set_vpnv4_nexthop_val_cmd,
3708 "no set vpnv4 next-hop A.B.C.D",
3709 NO_STR
3710 SET_STR
3711 "VPNv4 information\n"
3712 "VPNv4 next-hop address\n"
3713 "IP address of next hop\n")
3714
3715DEFUN (set_originator_id,
3716 set_originator_id_cmd,
3717 "set originator-id A.B.C.D",
3718 SET_STR
3719 "BGP originator ID attribute\n"
3720 "IP address of originator\n")
3721{
3722 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3723}
3724
3725DEFUN (no_set_originator_id,
3726 no_set_originator_id_cmd,
3727 "no set originator-id",
3728 NO_STR
3729 SET_STR
3730 "BGP originator ID attribute\n")
3731{
3732 if (argc == 0)
3733 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3734
3735 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3736}
3737
3738ALIAS (no_set_originator_id,
3739 no_set_originator_id_val_cmd,
3740 "no set originator-id A.B.C.D",
3741 NO_STR
3742 SET_STR
3743 "BGP originator ID attribute\n"
3744 "IP address of originator\n")
3745
41367172
PJ
3746DEFUN (set_pathlimit_ttl,
3747 set_pathlimit_ttl_cmd,
3748 "set pathlimit ttl <1-255>",
3749 SET_STR
3750 "BGP AS-Pathlimit attribute\n"
3751 "Set AS-Path Hop-count TTL\n")
3752{
3753 return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]);
3754}
3755
3756DEFUN (no_set_pathlimit_ttl,
3757 no_set_pathlimit_ttl_cmd,
3758 "no set pathlimit ttl",
3759 NO_STR
3760 SET_STR
3761 "BGP AS-Pathlimit attribute\n"
3762 "Set AS-Path Hop-count TTL\n")
3763{
3764 if (argc == 0)
3765 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL);
3766
3767 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]);
3768}
3769
3770ALIAS (no_set_pathlimit_ttl,
3771 no_set_pathlimit_ttl_val_cmd,
3772 "no set pathlimit ttl <1-255>",
3773 NO_STR
3774 MATCH_STR
3775 "BGP AS-Pathlimit attribute\n"
3776 "Set AS-Path Hop-count TTL\n")
3777
3778DEFUN (match_pathlimit_as,
3779 match_pathlimit_as_cmd,
3780 "match pathlimit as <1-65535>",
3781 MATCH_STR
3782 "BGP AS-Pathlimit attribute\n"
3783 "Match Pathlimit AS number\n")
3784{
3785 return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]);
3786}
3787
3788DEFUN (no_match_pathlimit_as,
3789 no_match_pathlimit_as_cmd,
3790 "no match pathlimit as",
3791 NO_STR
3792 MATCH_STR
3793 "BGP AS-Pathlimit attribute\n"
3794 "Match Pathlimit AS number\n")
3795{
3796 if (argc == 0)
3797 return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL);
3798
3799 return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]);
3800}
3801
3802ALIAS (no_match_pathlimit_as,
3803 no_match_pathlimit_as_val_cmd,
3804 "no match pathlimit as <1-65535>",
3805 NO_STR
3806 MATCH_STR
3807 "BGP AS-Pathlimit attribute\n"
3808 "Match Pathlimit ASN\n")
3809
718e3744 3810\f
3811/* Initialization of route map. */
3812void
94f2b392 3813bgp_route_map_init (void)
718e3744 3814{
3815 route_map_init ();
3816 route_map_init_vty ();
3817 route_map_add_hook (bgp_route_map_update);
3818 route_map_delete_hook (bgp_route_map_update);
3819
fee0f4c6 3820 route_map_install_match (&route_match_peer_cmd);
718e3744 3821 route_map_install_match (&route_match_ip_address_cmd);
3822 route_map_install_match (&route_match_ip_next_hop_cmd);
c1643bb7 3823 route_map_install_match (&route_match_ip_route_source_cmd);
718e3744 3824 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3825 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
c1643bb7 3826 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
718e3744 3827 route_map_install_match (&route_match_aspath_cmd);
3828 route_map_install_match (&route_match_community_cmd);
73ffb25b 3829 route_map_install_match (&route_match_ecommunity_cmd);
718e3744 3830 route_map_install_match (&route_match_metric_cmd);
3831 route_map_install_match (&route_match_origin_cmd);
3832
3833 route_map_install_set (&route_set_ip_nexthop_cmd);
3834 route_map_install_set (&route_set_local_pref_cmd);
3835 route_map_install_set (&route_set_weight_cmd);
3836 route_map_install_set (&route_set_metric_cmd);
3837 route_map_install_set (&route_set_aspath_prepend_cmd);
841f7a57 3838 route_map_install_set (&route_set_aspath_exclude_cmd);
718e3744 3839 route_map_install_set (&route_set_origin_cmd);
3840 route_map_install_set (&route_set_atomic_aggregate_cmd);
3841 route_map_install_set (&route_set_aggregator_as_cmd);
3842 route_map_install_set (&route_set_community_cmd);
3843 route_map_install_set (&route_set_community_delete_cmd);
3844 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3845 route_map_install_set (&route_set_originator_id_cmd);
3846 route_map_install_set (&route_set_ecommunity_rt_cmd);
3847 route_map_install_set (&route_set_ecommunity_soo_cmd);
3848
fee0f4c6 3849 install_element (RMAP_NODE, &match_peer_cmd);
3850 install_element (RMAP_NODE, &match_peer_local_cmd);
3851 install_element (RMAP_NODE, &no_match_peer_cmd);
3852 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3853 install_element (RMAP_NODE, &no_match_peer_local_cmd);
718e3744 3854 install_element (RMAP_NODE, &match_ip_address_cmd);
3855 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3856 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3857 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3858 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3859 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
c1643bb7 3860 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3861 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3862 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
718e3744 3863
3864 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3865 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3866 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3867 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3868 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3869 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
c1643bb7 3870 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3871 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3872 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
718e3744 3873
3874 install_element (RMAP_NODE, &match_aspath_cmd);
3875 install_element (RMAP_NODE, &no_match_aspath_cmd);
3876 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3877 install_element (RMAP_NODE, &match_metric_cmd);
3878 install_element (RMAP_NODE, &no_match_metric_cmd);
3879 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3880 install_element (RMAP_NODE, &match_community_cmd);
3881 install_element (RMAP_NODE, &match_community_exact_cmd);
3882 install_element (RMAP_NODE, &no_match_community_cmd);
3883 install_element (RMAP_NODE, &no_match_community_val_cmd);
3884 install_element (RMAP_NODE, &no_match_community_exact_cmd);
73ffb25b 3885 install_element (RMAP_NODE, &match_ecommunity_cmd);
3886 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3887 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
718e3744 3888 install_element (RMAP_NODE, &match_origin_cmd);
3889 install_element (RMAP_NODE, &no_match_origin_cmd);
3890 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3891
3892 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
af5cd0a5 3893 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
718e3744 3894 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3895 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3896 install_element (RMAP_NODE, &set_local_pref_cmd);
3897 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3898 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3899 install_element (RMAP_NODE, &set_weight_cmd);
3900 install_element (RMAP_NODE, &no_set_weight_cmd);
3901 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3902 install_element (RMAP_NODE, &set_metric_cmd);
73ffb25b 3903 install_element (RMAP_NODE, &set_metric_addsub_cmd);
718e3744 3904 install_element (RMAP_NODE, &no_set_metric_cmd);
3905 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3906 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
841f7a57 3907 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
718e3744 3908 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3909 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
841f7a57
DO
3910 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3911 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
718e3744 3912 install_element (RMAP_NODE, &set_origin_cmd);
3913 install_element (RMAP_NODE, &no_set_origin_cmd);
3914 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3915 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3916 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3917 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3918 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3919 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3920 install_element (RMAP_NODE, &set_community_cmd);
3921 install_element (RMAP_NODE, &set_community_none_cmd);
3922 install_element (RMAP_NODE, &no_set_community_cmd);
3923 install_element (RMAP_NODE, &no_set_community_val_cmd);
3924 install_element (RMAP_NODE, &no_set_community_none_cmd);
3925 install_element (RMAP_NODE, &set_community_delete_cmd);
3926 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3927 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3928 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3929 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3930 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3931 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3932 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3933 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3934 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3935 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3936 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3937 install_element (RMAP_NODE, &set_originator_id_cmd);
3938 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3939 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3940
3941#ifdef HAVE_IPV6
3942 route_map_install_match (&route_match_ipv6_address_cmd);
3943 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3944 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3945 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3946 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
41367172 3947
718e3744 3948 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3949 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3950 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3951 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3952 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3953 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3954 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3955 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3956 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3957 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3958 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3959 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3960#endif /* HAVE_IPV6 */
41367172
PJ
3961
3962 /* AS-Pathlimit */
3963 route_map_install_match (&route_match_pathlimit_as_cmd);
3964 route_map_install_set (&route_set_pathlimit_ttl_cmd);
3965
3966 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3967 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3968 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3969 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3970 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3971 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
718e3744 3972}