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