]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_routemap.c
[bgpd] Merge AS4 support
[mirror_frr.git] / bgpd / bgp_routemap.c
1 /* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-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
53 o 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
60 ip route-source : Done
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
90 pathlimit : Done
91
92 o Local extention
93
94 set ipv6 next-hop global: Done
95 set ipv6 next-hop local : Done
96 set pathlimit ttl : Done
97 match pathlimit as : Done
98
99 */
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 */
104 static void *
105 route_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
127 static void
128 route_pathlimit_free (void *rule)
129 {
130 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
131 }
132
133 static route_map_result_t
134 route_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' */
154 struct 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. */
163 static route_map_result_t
164 route_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. */
182 struct 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 };
189 \f
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. */
195 static route_map_result_t
196 route_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;
203 struct listnode *node, *nnode;
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 {
219 int ret;
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))
223 ret = RMAP_MATCH;
224 else
225 ret = RMAP_NOMATCH;
226
227 sockunion_free (su2);
228 return ret;
229 }
230 sockunion_free (su2);
231
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;
242 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
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
254 static void *
255 route_match_peer_compile (const char *arg)
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. */
272 static void
273 route_match_peer_free (void *rule)
274 {
275 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
276 }
277
278 /* Route map commands for ip address matching. */
279 struct 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
287 /* `match ip address IP_ACCESS_LIST' */
288
289 /* Match function should return 1 if match is success else return
290 zero. */
291 static route_map_result_t
292 route_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. */
312 static void *
313 route_match_ip_address_compile (const char *arg)
314 {
315 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
316 }
317
318 /* Free route map's compiled `ip address' value. */
319 static void
320 route_match_ip_address_free (void *rule)
321 {
322 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
323 }
324
325 /* Route map commands for ip address matching. */
326 struct 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. */
337 static route_map_result_t
338 route_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. */
364 static void *
365 route_match_ip_next_hop_compile (const char *arg)
366 {
367 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
368 }
369
370 /* Free route map's compiled `ip address' value. */
371 static void
372 route_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. */
378 struct 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
386 /* `match ip route-source ACCESS-LIST' */
387
388 /* Match function return 1 if match is success else return zero. */
389 static route_map_result_t
390 route_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. */
422 static void *
423 route_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. */
429 static void
430 route_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. */
436 struct 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
444 /* `match ip address prefix-list PREFIX_LIST' */
445
446 static route_map_result_t
447 route_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
464 static void *
465 route_match_ip_address_prefix_list_compile (const char *arg)
466 {
467 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
468 }
469
470 static void
471 route_match_ip_address_prefix_list_free (void *rule)
472 {
473 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
474 }
475
476 struct 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
486 static route_map_result_t
487 route_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
511 static void *
512 route_match_ip_next_hop_prefix_list_compile (const char *arg)
513 {
514 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
515 }
516
517 static void
518 route_match_ip_next_hop_prefix_list_free (void *rule)
519 {
520 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
521 }
522
523 struct 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
531 /* `match ip route-source prefix-list PREFIX_LIST' */
532
533 static route_map_result_t
534 route_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
564 static void *
565 route_match_ip_route_source_prefix_list_compile (const char *arg)
566 {
567 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
568 }
569
570 static void
571 route_match_ip_route_source_prefix_list_free (void *rule)
572 {
573 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
574 }
575
576 struct 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
584 /* `match metric METRIC' */
585
586 /* Match function return 1 if match is success else return zero. */
587 static route_map_result_t
588 route_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 */
608 static void *
609 route_match_metric_compile (const char *arg)
610 {
611 u_int32_t *med;
612 char *endptr = NULL;
613 unsigned long tmpval;
614
615 tmpval = strtoul (arg, &endptr, 10);
616 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
617 return NULL;
618
619 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
620
621 if (!med)
622 return med;
623
624 *med = tmpval;
625 return med;
626 }
627
628 /* Free route map's compiled `match metric' value. */
629 static void
630 route_match_metric_free (void *rule)
631 {
632 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
633 }
634
635 /* Route map commands for metric matching. */
636 struct 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 */
647 static route_map_result_t
648 route_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. */
670 static void *
671 route_match_aspath_compile (const char *arg)
672 {
673 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
674 }
675
676 /* Compile function for as-path match. */
677 static void
678 route_match_aspath_free (void *rule)
679 {
680 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
681 }
682
683 /* Route map commands for aspath matching. */
684 struct 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 };
691 \f
692 /* `match community COMMUNIY' */
693 struct rmap_community
694 {
695 char *name;
696 int exact;
697 };
698
699 /* Match function for community match. */
700 static route_map_result_t
701 route_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
713 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
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. */
732 static void *
733 route_match_community_compile (const char *arg)
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. */
758 static void
759 route_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. */
768 struct 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
776 /* Match function for extcommunity match. */
777 static route_map_result_t
778 route_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;
787
788 if (!bgp_info->attr->extra)
789 return RMAP_NOMATCH;
790
791 list = community_list_lookup (bgp_clist, (char *) rule,
792 EXTCOMMUNITY_LIST_MASTER);
793 if (! list)
794 return RMAP_NOMATCH;
795
796 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
797 return RMAP_MATCH;
798 }
799 return RMAP_NOMATCH;
800 }
801
802 /* Compile function for extcommunity match. */
803 static void *
804 route_match_ecommunity_compile (const char *arg)
805 {
806 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
807 }
808
809 /* Compile function for extcommunity match. */
810 static void
811 route_match_ecommunity_free (void *rule)
812 {
813 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
814 }
815
816 /* Route map commands for community matching. */
817 struct 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
825 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
826 and `address-family vpnv4'. */
827 \f
828 /* `match origin' */
829 static route_map_result_t
830 route_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
848 static void *
849 route_match_origin_compile (const char *arg)
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. */
866 static void
867 route_match_origin_free (void *rule)
868 {
869 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
870 }
871
872 /* Route map commands for origin matching. */
873 struct 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. */
883 struct rmap_ip_nexthop_set
884 {
885 struct in_addr *address;
886 int peer_address;
887 };
888
889 static route_map_result_t
890 route_set_ip_nexthop (void *rule, struct prefix *prefix,
891 route_map_object_t type, void *object)
892 {
893 struct rmap_ip_nexthop_set *rins = rule;
894 struct in_addr peer_address;
895 struct bgp_info *bgp_info;
896 struct peer *peer;
897
898 if (type == RMAP_BGP)
899 {
900 bgp_info = object;
901 peer = bgp_info->peer;
902
903 if (rins->peer_address)
904 {
905 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
906 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
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 }
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. */
936 static void *
937 route_set_ip_nexthop_compile (const char *arg)
938 {
939 struct rmap_ip_nexthop_set *rins;
940 struct in_addr *address = NULL;
941 int peer_address = 0;
942 int ret;
943
944 if (strcmp (arg, "peer-address") == 0)
945 peer_address = 1;
946 else
947 {
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 }
956 }
957
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;
965 }
966
967 /* Free route map's compiled `ip nexthop' value. */
968 static void
969 route_set_ip_nexthop_free (void *rule)
970 {
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);
977 }
978
979 /* Route map commands for ip nexthop set. */
980 struct 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. */
991 static route_map_result_t
992 route_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. */
1013 static void *
1014 route_set_local_pref_compile (const char *arg)
1015 {
1016 unsigned long tmp;
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;
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
1035 return local_pref;
1036 }
1037
1038 /* Free route map's local preference value. */
1039 static void
1040 route_set_local_pref_free (void *rule)
1041 {
1042 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1043 }
1044
1045 /* Set local preference rule structure. */
1046 struct 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. */
1057 static route_map_result_t
1058 route_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. */
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;
1075 }
1076
1077 return RMAP_OKAY;
1078 }
1079
1080 /* set local preference compilation. */
1081 static void *
1082 route_set_weight_compile (const char *arg)
1083 {
1084 unsigned long tmp;
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
1092
1093 tmp = strtoul (arg, &endptr, 10);
1094 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1095 return NULL;
1096
1097 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1098
1099 if (weight == NULL)
1100 return weight;
1101
1102 *weight = tmp;
1103
1104 return weight;
1105 }
1106
1107 /* Free route map's local preference value. */
1108 static void
1109 route_set_weight_free (void *rule)
1110 {
1111 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1112 }
1113
1114 /* Set local preference rule structure. */
1115 struct 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. */
1126 static route_map_result_t
1127 route_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 {
1155 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1156 bgp_info->attr->med = BGP_MED_MAX - 1;
1157 else
1158 bgp_info->attr->med += metric_val;
1159 }
1160 else if (strncmp (metric, "-", 1) == 0)
1161 {
1162 if (bgp_info->attr->med <= metric_val)
1163 bgp_info->attr->med = 0;
1164 else
1165 bgp_info->attr->med -= metric_val;
1166 }
1167 }
1168 }
1169 return RMAP_OKAY;
1170 }
1171
1172 /* set metric compilation. */
1173 static void *
1174 route_set_metric_compile (const char *arg)
1175 {
1176 u_int32_t metric;
1177 unsigned long larg;
1178 char *endptr = NULL;
1179
1180 if (all_digit (arg))
1181 {
1182 /* set metric value check*/
1183 larg = strtoul (arg, &endptr, 10);
1184 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
1185 return NULL;
1186 metric = larg;
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
1196 larg = strtoul (arg+1, &endptr, 10);
1197 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
1198 return NULL;
1199 metric = larg;
1200 }
1201
1202 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1203 }
1204
1205 /* Free route map's compiled `set metric' value. */
1206 static void
1207 route_set_metric_free (void *rule)
1208 {
1209 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1210 }
1211
1212 /* Set metric rule structure. */
1213 struct 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. */
1224 static route_map_result_t
1225 route_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. */
1249 static void *
1250 route_set_aspath_prepend_compile (const char *arg)
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. */
1261 static void
1262 route_set_aspath_prepend_free (void *rule)
1263 {
1264 struct aspath *aspath = rule;
1265 aspath_free (aspath);
1266 }
1267
1268 /* Set metric rule structure. */
1269 struct 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' */
1278 struct rmap_com_set
1279 {
1280 struct community *com;
1281 int additive;
1282 int none;
1283 };
1284
1285 /* For community set mechanism. */
1286 static route_map_result_t
1287 route_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;
1296
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);
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);
1323 new = community_uniq_sort (merge);
1324 community_free (merge);
1325 }
1326 else
1327 new = community_dup (rcs->com);
1328
1329 /* will be interned by caller if required */
1330 attr->community = new;
1331
1332 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1333 }
1334
1335 return RMAP_OKAY;
1336 }
1337
1338 /* Compile function for set community. */
1339 static void *
1340 route_set_community_compile (const char *arg)
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. */
1381 static void
1382 route_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. */
1392 struct 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
1400 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
1401
1402 /* For community set mechanism. */
1403 static route_map_result_t
1404 route_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;
1419 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
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. */
1446 static void *
1447 route_set_community_delete_compile (const char *arg)
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. */
1467 static void
1468 route_set_community_delete_free (void *rule)
1469 {
1470 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1471 }
1472
1473 /* Set community rule structure. */
1474 struct 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. */
1485 static route_map_result_t
1486 route_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. */
1503 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1504
1505 if (old_ecom)
1506 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1507 else
1508 new_ecom = ecommunity_dup (ecom);
1509
1510 bgp_info->attr->extra->ecommunity = new_ecom;
1511
1512 if (old_ecom)
1513 ecommunity_free (old_ecom);
1514
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. */
1521 static void *
1522 route_set_ecommunity_rt_compile (const char *arg)
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. */
1533 static void
1534 route_set_ecommunity_rt_free (void *rule)
1535 {
1536 struct ecommunity *ecom = rule;
1537 ecommunity_free (ecom);
1538 }
1539
1540 /* Set community rule structure. */
1541 struct 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. */
1552 static route_map_result_t
1553 route_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);
1568 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
1569 }
1570 return RMAP_OKAY;
1571 }
1572
1573 /* Compile function for set community. */
1574 static void *
1575 route_set_ecommunity_soo_compile (const char *arg)
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. */
1587 static void
1588 route_set_ecommunity_soo_free (void *rule)
1589 {
1590 struct ecommunity *ecom = rule;
1591 ecommunity_free (ecom);
1592 }
1593
1594 /* Set community rule structure. */
1595 struct 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. */
1606 static route_map_result_t
1607 route_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. */
1624 static void *
1625 route_set_origin_compile (const char *arg)
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. */
1642 static void
1643 route_set_origin_free (void *rule)
1644 {
1645 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1646 }
1647
1648 /* Set metric rule structure. */
1649 struct 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. */
1660 static route_map_result_t
1661 route_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. */
1676 static void *
1677 route_set_atomic_aggregate_compile (const char *arg)
1678 {
1679 return (void *)1;
1680 }
1681
1682 /* Compile function for atomic aggregate. */
1683 static void
1684 route_set_atomic_aggregate_free (void *rule)
1685 {
1686 return;
1687 }
1688
1689 /* Set atomic aggregate rule structure. */
1690 struct 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' */
1699 struct aggregator
1700 {
1701 as_t as;
1702 struct in_addr address;
1703 };
1704
1705 static route_map_result_t
1706 route_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;
1711 struct attr_extra *ae;
1712
1713 if (type == RMAP_BGP)
1714 {
1715 bgp_info = object;
1716 aggregator = rule;
1717 ae = bgp_attr_extra_get (bgp_info->attr);
1718
1719 ae->aggregator_as = aggregator->as;
1720 ae->aggregator_addr = aggregator->address;
1721 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1722 }
1723
1724 return RMAP_OKAY;
1725 }
1726
1727 static void *
1728 route_set_aggregator_as_compile (const char *arg)
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
1745 static void
1746 route_set_aggregator_as_free (void *rule)
1747 {
1748 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1749 }
1750
1751 struct 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
1762 static route_map_result_t
1763 route_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
1780 static void *
1781 route_match_ipv6_address_compile (const char *arg)
1782 {
1783 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1784 }
1785
1786 static void
1787 route_match_ipv6_address_free (void *rule)
1788 {
1789 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1790 }
1791
1792 /* Route map commands for ip address matching. */
1793 struct 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
1803 static route_map_result_t
1804 route_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;
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))
1819 return RMAP_MATCH;
1820
1821 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1822 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
1823 return RMAP_MATCH;
1824
1825 return RMAP_NOMATCH;
1826 }
1827
1828 return RMAP_NOMATCH;
1829 }
1830
1831 static void *
1832 route_match_ipv6_next_hop_compile (const char *arg)
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
1849 static void
1850 route_match_ipv6_next_hop_free (void *rule)
1851 {
1852 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1853 }
1854
1855 struct 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
1865 static route_map_result_t
1866 route_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
1883 static void *
1884 route_match_ipv6_address_prefix_list_compile (const char *arg)
1885 {
1886 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1887 }
1888
1889 static void
1890 route_match_ipv6_address_prefix_list_free (void *rule)
1891 {
1892 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1893 }
1894
1895 struct 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. */
1906 static route_map_result_t
1907 route_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. */
1920 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
1921
1922 /* Set nexthop length. */
1923 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1924 bgp_info->attr->extra->mp_nexthop_len = 16;
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. */
1932 static void *
1933 route_set_ipv6_nexthop_global_compile (const char *arg)
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. */
1952 static void
1953 route_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. */
1959 struct 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. */
1970 static route_map_result_t
1971 route_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. */
1984 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
1985
1986 /* Set nexthop length. */
1987 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1988 bgp_info->attr->extra->mp_nexthop_len = 32;
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. */
1996 static void *
1997 route_set_ipv6_nexthop_local_compile (const char *arg)
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. */
2016 static void
2017 route_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. */
2023 struct 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
2034 static route_map_result_t
2035 route_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. */
2048 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
2049 }
2050
2051 return RMAP_OKAY;
2052 }
2053
2054 static void *
2055 route_set_vpnv4_nexthop_compile (const char *arg)
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
2073 static void
2074 route_set_vpnv4_nexthop_free (void *rule)
2075 {
2076 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2077 }
2078
2079 /* Route map commands for ip nexthop set. */
2080 struct 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. */
2091 static route_map_result_t
2092 route_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);
2103 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
2104 }
2105
2106 return RMAP_OKAY;
2107 }
2108
2109 /* Compile function for originator-id set. */
2110 static void *
2111 route_set_originator_id_compile (const char *arg)
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. */
2130 static void
2131 route_set_originator_id_free (void *rule)
2132 {
2133 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2134 }
2135
2136 /* Set metric rule structure. */
2137 struct 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. */
2146 static int
2147 bgp_route_match_add (struct vty *vty, struct route_map_index *index,
2148 const char *command, const char *arg)
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;
2160 case RMAP_COMPILE_ERROR:
2161 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2162 return CMD_WARNING;
2163 }
2164 }
2165 return CMD_SUCCESS;
2166 }
2167
2168 /* Delete bgp route map rule. */
2169 static int
2170 bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
2171 const char *command, const char *arg)
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;
2183 case RMAP_COMPILE_ERROR:
2184 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2185 return CMD_WARNING;
2186 }
2187 }
2188 return CMD_SUCCESS;
2189 }
2190
2191 /* Add bgp route map rule. */
2192 static int
2193 bgp_route_set_add (struct vty *vty, struct route_map_index *index,
2194 const char *command, const char *arg)
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;
2206 case RMAP_COMPILE_ERROR:
2207 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2208 return CMD_WARNING;
2209 }
2210 }
2211 return CMD_SUCCESS;
2212 }
2213
2214 /* Delete bgp route map rule. */
2215 static int
2216 bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
2217 const char *command, const char *arg)
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;
2229 case RMAP_COMPILE_ERROR:
2230 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2231 return CMD_WARNING;
2232 }
2233 }
2234 return CMD_SUCCESS;
2235 }
2236
2237 /* Hook function for updating route_map assignment. */
2238 static void
2239 bgp_route_map_update (const char *unused)
2240 {
2241 int i;
2242 afi_t afi;
2243 safi_t safi;
2244 int direct;
2245 struct listnode *node, *nnode;
2246 struct listnode *mnode, *mnnode;
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. */
2255 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2256 {
2257 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
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
2264 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
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 }
2279 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
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
2286 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
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. */
2304 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2305 {
2306 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
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. */
2321 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
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. */
2338 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
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
2354 DEFUN (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
2365 DEFUN (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
2375 DEFUN (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
2388 ALIAS (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
2397 ALIAS (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
2405 DEFUN (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
2418 DEFUN (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
2432 ALIAS (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
2443 DEFUN (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
2456 DEFUN (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
2470 ALIAS (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
2481 DEFUN (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
2494 DEFUN (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
2508 ALIAS (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
2519 DEFUN (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
2531 DEFUN (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
2546 ALIAS (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
2556 DEFUN (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
2568 DEFUN (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
2583 ALIAS (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
2593 DEFUN (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
2605 DEFUN (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
2620 ALIAS (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
2630 DEFUN (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
2640 DEFUN (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
2653 ALIAS (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
2661 DEFUN (match_community,
2662 match_community_cmd,
2663 "match community (<1-99>|<100-500>|WORD)",
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
2673 DEFUN (match_community_exact,
2674 match_community_exact_cmd,
2675 "match community (<1-99>|<100-500>|WORD) exact-match",
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
2698 DEFUN (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
2708 ALIAS (no_match_community,
2709 no_match_community_val_cmd,
2710 "no match community (<1-99>|<100-500>|WORD)",
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
2718 ALIAS (no_match_community,
2719 no_match_community_exact_cmd,
2720 "no match community (<1-99>|<100-500>|WORD) exact-match",
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
2729 DEFUN (match_ecommunity,
2730 match_ecommunity_cmd,
2731 "match extcommunity (<1-99>|<100-500>|WORD)",
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
2741 DEFUN (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
2751 ALIAS (no_match_ecommunity,
2752 no_match_ecommunity_val_cmd,
2753 "no match extcommunity (<1-99>|<100-500>|WORD)",
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
2761 DEFUN (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
2771 DEFUN (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
2781 ALIAS (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
2789 DEFUN (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
2808 DEFUN (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
2818 ALIAS (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
2828 DEFUN (set_ip_nexthop,
2829 set_ip_nexthop_cmd,
2830 "set ip next-hop A.B.C.D",
2831 SET_STR
2832 IP_STR
2833 "Next hop address\n"
2834 "IP address of next hop\n")
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
2849 DEFUN (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
2860 DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
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
2873 DEFUN (no_set_ip_nexthop,
2874 no_set_ip_nexthop_cmd,
2875 "no set ip next-hop",
2876 NO_STR
2877 SET_STR
2878 "Next hop address\n")
2879 {
2880 if (argc == 0)
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
2886 ALIAS (no_set_ip_nexthop,
2887 no_set_ip_nexthop_val_cmd,
2888 "no set ip next-hop A.B.C.D",
2889 NO_STR
2890 SET_STR
2891 IP_STR
2892 "Next hop address\n"
2893 "IP address of next hop\n")
2894
2895 DEFUN (set_metric,
2896 set_metric_cmd,
2897 "set metric <0-4294967295>",
2898 SET_STR
2899 "Metric value for destination routing protocol\n"
2900 "Metric value\n")
2901 {
2902 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2903 }
2904
2905 ALIAS (set_metric,
2906 set_metric_addsub_cmd,
2907 "set metric <+/-metric>",
2908 SET_STR
2909 "Metric value for destination routing protocol\n"
2910 "Add or subtract metric\n")
2911
2912 DEFUN (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
2925 ALIAS (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
2933 DEFUN (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
2943 DEFUN (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
2956 ALIAS (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
2964 DEFUN (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
2974 DEFUN (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
2987 ALIAS (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
2995 DEFUN (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
3013 DEFUN (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 {
3021 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3022 }
3023
3024 ALIAS (no_set_aspath_prepend,
3025 no_set_aspath_prepend_val_cmd,
3026 "no set as-path prepend .<1-65535>",
3027 NO_STR
3028 SET_STR
3029 "Prepend string for a BGP AS-path attribute\n"
3030 "Prepend to the as-path\n"
3031 "AS number\n")
3032
3033 DEFUN (set_community,
3034 set_community_cmd,
3035 "set community .AA:NN",
3036 SET_STR
3037 "BGP community attribute\n"
3038 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3039 {
3040 int i;
3041 int first = 0;
3042 int additive = 0;
3043 struct buffer *b;
3044 struct community *com = NULL;
3045 char *str;
3046 char *argstr;
3047 int ret;
3048
3049 b = buffer_new (1024);
3050
3051 for (i = 0; i < argc; i++)
3052 {
3053 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3054 {
3055 additive = 1;
3056 continue;
3057 }
3058
3059 if (first)
3060 buffer_putc (b, ' ');
3061 else
3062 first = 1;
3063
3064 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3065 {
3066 buffer_putstr (b, "internet");
3067 continue;
3068 }
3069 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3070 {
3071 buffer_putstr (b, "local-AS");
3072 continue;
3073 }
3074 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3075 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3076 {
3077 buffer_putstr (b, "no-advertise");
3078 continue;
3079 }
3080 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3081 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3082 {
3083 buffer_putstr (b, "no-export");
3084 continue;
3085 }
3086 buffer_putstr (b, argv[i]);
3087 }
3088 buffer_putc (b, '\0');
3089
3090 /* Fetch result string then compile it to communities attribute. */
3091 str = buffer_getstr (b);
3092 buffer_free (b);
3093
3094 if (str)
3095 {
3096 com = community_str2com (str);
3097 XFREE (MTYPE_TMP, str);
3098 }
3099
3100 /* Can't compile user input into communities attribute. */
3101 if (! com)
3102 {
3103 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3104 return CMD_WARNING;
3105 }
3106
3107 /* Set communites attribute string. */
3108 str = community_str (com);
3109
3110 if (additive)
3111 {
3112 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3113 strcpy (argstr, str);
3114 strcpy (argstr + strlen (str), " additive");
3115 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3116 XFREE (MTYPE_TMP, argstr);
3117 }
3118 else
3119 ret = bgp_route_set_add (vty, vty->index, "community", str);
3120
3121 community_free (com);
3122
3123 return ret;
3124 }
3125
3126 DEFUN (set_community_none,
3127 set_community_none_cmd,
3128 "set community none",
3129 SET_STR
3130 "BGP community attribute\n"
3131 "No community attribute\n")
3132 {
3133 return bgp_route_set_add (vty, vty->index, "community", "none");
3134 }
3135
3136 DEFUN (no_set_community,
3137 no_set_community_cmd,
3138 "no set community",
3139 NO_STR
3140 SET_STR
3141 "BGP community attribute\n")
3142 {
3143 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3144 }
3145
3146 ALIAS (no_set_community,
3147 no_set_community_val_cmd,
3148 "no set community .AA:NN",
3149 NO_STR
3150 SET_STR
3151 "BGP community attribute\n"
3152 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3153
3154 ALIAS (no_set_community,
3155 no_set_community_none_cmd,
3156 "no set community none",
3157 NO_STR
3158 SET_STR
3159 "BGP community attribute\n"
3160 "No community attribute\n")
3161
3162 DEFUN (set_community_delete,
3163 set_community_delete_cmd,
3164 "set comm-list (<1-99>|<100-500>|WORD) delete",
3165 SET_STR
3166 "set BGP community list (for deletion)\n"
3167 "Community-list number (standard)\n"
3168 "Communitly-list number (expanded)\n"
3169 "Community-list name\n"
3170 "Delete matching communities\n")
3171 {
3172 char *str;
3173
3174 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3175 strcpy (str, argv[0]);
3176 strcpy (str + strlen (argv[0]), " delete");
3177
3178 bgp_route_set_add (vty, vty->index, "comm-list", str);
3179
3180 XFREE (MTYPE_TMP, str);
3181 return CMD_SUCCESS;
3182 }
3183
3184 DEFUN (no_set_community_delete,
3185 no_set_community_delete_cmd,
3186 "no set comm-list",
3187 NO_STR
3188 SET_STR
3189 "set BGP community list (for deletion)\n")
3190 {
3191 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3192 }
3193
3194 ALIAS (no_set_community_delete,
3195 no_set_community_delete_val_cmd,
3196 "no set comm-list (<1-99>|<100-500>|WORD) delete",
3197 NO_STR
3198 SET_STR
3199 "set BGP community list (for deletion)\n"
3200 "Community-list number (standard)\n"
3201 "Communitly-list number (expanded)\n"
3202 "Community-list name\n"
3203 "Delete matching communities\n")
3204
3205 DEFUN (set_ecommunity_rt,
3206 set_ecommunity_rt_cmd,
3207 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3208 SET_STR
3209 "BGP extended community attribute\n"
3210 "Route Target extened communityt\n"
3211 "VPN extended community\n")
3212 {
3213 int ret;
3214 char *str;
3215
3216 str = argv_concat (argv, argc, 0);
3217 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3218 XFREE (MTYPE_TMP, str);
3219
3220 return ret;
3221 }
3222
3223 DEFUN (no_set_ecommunity_rt,
3224 no_set_ecommunity_rt_cmd,
3225 "no set extcommunity rt",
3226 NO_STR
3227 SET_STR
3228 "BGP extended community attribute\n"
3229 "Route Target extened communityt\n")
3230 {
3231 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3232 }
3233
3234 ALIAS (no_set_ecommunity_rt,
3235 no_set_ecommunity_rt_val_cmd,
3236 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3237 NO_STR
3238 SET_STR
3239 "BGP extended community attribute\n"
3240 "Route Target extened communityt\n"
3241 "VPN extended community\n")
3242
3243 DEFUN (set_ecommunity_soo,
3244 set_ecommunity_soo_cmd,
3245 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3246 SET_STR
3247 "BGP extended community attribute\n"
3248 "Site-of-Origin extended community\n"
3249 "VPN extended community\n")
3250 {
3251 int ret;
3252 char *str;
3253
3254 str = argv_concat (argv, argc, 0);
3255 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3256 XFREE (MTYPE_TMP, str);
3257 return ret;
3258 }
3259
3260 DEFUN (no_set_ecommunity_soo,
3261 no_set_ecommunity_soo_cmd,
3262 "no set extcommunity soo",
3263 NO_STR
3264 SET_STR
3265 "BGP extended community attribute\n"
3266 "Site-of-Origin extended community\n")
3267 {
3268 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3269 }
3270
3271 ALIAS (no_set_ecommunity_soo,
3272 no_set_ecommunity_soo_val_cmd,
3273 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3274 NO_STR
3275 SET_STR
3276 "BGP extended community attribute\n"
3277 "Site-of-Origin extended community\n"
3278 "VPN extended community\n")
3279
3280 DEFUN (set_origin,
3281 set_origin_cmd,
3282 "set origin (egp|igp|incomplete)",
3283 SET_STR
3284 "BGP origin code\n"
3285 "remote EGP\n"
3286 "local IGP\n"
3287 "unknown heritage\n")
3288 {
3289 if (strncmp (argv[0], "igp", 2) == 0)
3290 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3291 if (strncmp (argv[0], "egp", 1) == 0)
3292 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3293 if (strncmp (argv[0], "incomplete", 2) == 0)
3294 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3295
3296 return CMD_WARNING;
3297 }
3298
3299 DEFUN (no_set_origin,
3300 no_set_origin_cmd,
3301 "no set origin",
3302 NO_STR
3303 SET_STR
3304 "BGP origin code\n")
3305 {
3306 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3307 }
3308
3309 ALIAS (no_set_origin,
3310 no_set_origin_val_cmd,
3311 "no set origin (egp|igp|incomplete)",
3312 NO_STR
3313 SET_STR
3314 "BGP origin code\n"
3315 "remote EGP\n"
3316 "local IGP\n"
3317 "unknown heritage\n")
3318
3319 DEFUN (set_atomic_aggregate,
3320 set_atomic_aggregate_cmd,
3321 "set atomic-aggregate",
3322 SET_STR
3323 "BGP atomic aggregate attribute\n" )
3324 {
3325 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3326 }
3327
3328 DEFUN (no_set_atomic_aggregate,
3329 no_set_atomic_aggregate_cmd,
3330 "no set atomic-aggregate",
3331 NO_STR
3332 SET_STR
3333 "BGP atomic aggregate attribute\n" )
3334 {
3335 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3336 }
3337
3338 DEFUN (set_aggregator_as,
3339 set_aggregator_as_cmd,
3340 "set aggregator as CMD_AS_RANGE A.B.C.D",
3341 SET_STR
3342 "BGP aggregator attribute\n"
3343 "AS number of aggregator\n"
3344 "AS number\n"
3345 "IP address of aggregator\n")
3346 {
3347 int ret;
3348 as_t as;
3349 struct in_addr address;
3350 char *argstr;
3351
3352 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
3353
3354 ret = inet_aton (argv[1], &address);
3355 if (ret == 0)
3356 {
3357 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3358 return CMD_WARNING;
3359 }
3360
3361 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3362 strlen (argv[0]) + strlen (argv[1]) + 2);
3363
3364 sprintf (argstr, "%s %s", argv[0], argv[1]);
3365
3366 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3367
3368 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3369
3370 return ret;
3371 }
3372
3373 DEFUN (no_set_aggregator_as,
3374 no_set_aggregator_as_cmd,
3375 "no set aggregator as",
3376 NO_STR
3377 SET_STR
3378 "BGP aggregator attribute\n"
3379 "AS number of aggregator\n")
3380 {
3381 int ret;
3382 as_t as;
3383 struct in_addr address;
3384 char *argstr;
3385
3386 if (argv == 0)
3387 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3388
3389 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
3390
3391 ret = inet_aton (argv[1], &address);
3392 if (ret == 0)
3393 {
3394 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3395 return CMD_WARNING;
3396 }
3397
3398 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3399 strlen (argv[0]) + strlen (argv[1]) + 2);
3400
3401 sprintf (argstr, "%s %s", argv[0], argv[1]);
3402
3403 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3404
3405 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3406
3407 return ret;
3408 }
3409
3410 ALIAS (no_set_aggregator_as,
3411 no_set_aggregator_as_val_cmd,
3412 "no set aggregator as CMD_AS_RANGE A.B.C.D",
3413 NO_STR
3414 SET_STR
3415 "BGP aggregator attribute\n"
3416 "AS number of aggregator\n"
3417 "AS number\n"
3418 "IP address of aggregator\n")
3419
3420 \f
3421 #ifdef HAVE_IPV6
3422 DEFUN (match_ipv6_address,
3423 match_ipv6_address_cmd,
3424 "match ipv6 address WORD",
3425 MATCH_STR
3426 IPV6_STR
3427 "Match IPv6 address of route\n"
3428 "IPv6 access-list name\n")
3429 {
3430 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3431 }
3432
3433 DEFUN (no_match_ipv6_address,
3434 no_match_ipv6_address_cmd,
3435 "no match ipv6 address WORD",
3436 NO_STR
3437 MATCH_STR
3438 IPV6_STR
3439 "Match IPv6 address of route\n"
3440 "IPv6 access-list name\n")
3441 {
3442 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3443 }
3444
3445 DEFUN (match_ipv6_next_hop,
3446 match_ipv6_next_hop_cmd,
3447 "match ipv6 next-hop X:X::X:X",
3448 MATCH_STR
3449 IPV6_STR
3450 "Match IPv6 next-hop address of route\n"
3451 "IPv6 address of next hop\n")
3452 {
3453 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3454 }
3455
3456 DEFUN (no_match_ipv6_next_hop,
3457 no_match_ipv6_next_hop_cmd,
3458 "no match ipv6 next-hop X:X::X:X",
3459 NO_STR
3460 MATCH_STR
3461 IPV6_STR
3462 "Match IPv6 next-hop address of route\n"
3463 "IPv6 address of next hop\n")
3464 {
3465 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3466 }
3467
3468 DEFUN (match_ipv6_address_prefix_list,
3469 match_ipv6_address_prefix_list_cmd,
3470 "match ipv6 address prefix-list WORD",
3471 MATCH_STR
3472 IPV6_STR
3473 "Match address of route\n"
3474 "Match entries of prefix-lists\n"
3475 "IP prefix-list name\n")
3476 {
3477 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3478 }
3479
3480 DEFUN (no_match_ipv6_address_prefix_list,
3481 no_match_ipv6_address_prefix_list_cmd,
3482 "no match ipv6 address prefix-list WORD",
3483 NO_STR
3484 MATCH_STR
3485 IPV6_STR
3486 "Match address of route\n"
3487 "Match entries of prefix-lists\n"
3488 "IP prefix-list name\n")
3489 {
3490 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3491 }
3492
3493 DEFUN (set_ipv6_nexthop_global,
3494 set_ipv6_nexthop_global_cmd,
3495 "set ipv6 next-hop global X:X::X:X",
3496 SET_STR
3497 IPV6_STR
3498 "IPv6 next-hop address\n"
3499 "IPv6 global address\n"
3500 "IPv6 address of next hop\n")
3501 {
3502 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3503 }
3504
3505 DEFUN (no_set_ipv6_nexthop_global,
3506 no_set_ipv6_nexthop_global_cmd,
3507 "no set ipv6 next-hop global",
3508 NO_STR
3509 SET_STR
3510 IPV6_STR
3511 "IPv6 next-hop address\n"
3512 "IPv6 global address\n")
3513 {
3514 if (argc == 0)
3515 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3516
3517 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3518 }
3519
3520 ALIAS (no_set_ipv6_nexthop_global,
3521 no_set_ipv6_nexthop_global_val_cmd,
3522 "no set ipv6 next-hop global X:X::X:X",
3523 NO_STR
3524 SET_STR
3525 IPV6_STR
3526 "IPv6 next-hop address\n"
3527 "IPv6 global address\n"
3528 "IPv6 address of next hop\n")
3529
3530 DEFUN (set_ipv6_nexthop_local,
3531 set_ipv6_nexthop_local_cmd,
3532 "set ipv6 next-hop local X:X::X:X",
3533 SET_STR
3534 IPV6_STR
3535 "IPv6 next-hop address\n"
3536 "IPv6 local address\n"
3537 "IPv6 address of next hop\n")
3538 {
3539 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3540 }
3541
3542 DEFUN (no_set_ipv6_nexthop_local,
3543 no_set_ipv6_nexthop_local_cmd,
3544 "no set ipv6 next-hop local",
3545 NO_STR
3546 SET_STR
3547 IPV6_STR
3548 "IPv6 next-hop address\n"
3549 "IPv6 local address\n")
3550 {
3551 if (argc == 0)
3552 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3553
3554 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3555 }
3556
3557 ALIAS (no_set_ipv6_nexthop_local,
3558 no_set_ipv6_nexthop_local_val_cmd,
3559 "no set ipv6 next-hop local X:X::X:X",
3560 NO_STR
3561 SET_STR
3562 IPV6_STR
3563 "IPv6 next-hop address\n"
3564 "IPv6 local address\n"
3565 "IPv6 address of next hop\n")
3566 #endif /* HAVE_IPV6 */
3567
3568 DEFUN (set_vpnv4_nexthop,
3569 set_vpnv4_nexthop_cmd,
3570 "set vpnv4 next-hop A.B.C.D",
3571 SET_STR
3572 "VPNv4 information\n"
3573 "VPNv4 next-hop address\n"
3574 "IP address of next hop\n")
3575 {
3576 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3577 }
3578
3579 DEFUN (no_set_vpnv4_nexthop,
3580 no_set_vpnv4_nexthop_cmd,
3581 "no set vpnv4 next-hop",
3582 NO_STR
3583 SET_STR
3584 "VPNv4 information\n"
3585 "VPNv4 next-hop address\n")
3586 {
3587 if (argc == 0)
3588 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3589
3590 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3591 }
3592
3593 ALIAS (no_set_vpnv4_nexthop,
3594 no_set_vpnv4_nexthop_val_cmd,
3595 "no set vpnv4 next-hop A.B.C.D",
3596 NO_STR
3597 SET_STR
3598 "VPNv4 information\n"
3599 "VPNv4 next-hop address\n"
3600 "IP address of next hop\n")
3601
3602 DEFUN (set_originator_id,
3603 set_originator_id_cmd,
3604 "set originator-id A.B.C.D",
3605 SET_STR
3606 "BGP originator ID attribute\n"
3607 "IP address of originator\n")
3608 {
3609 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3610 }
3611
3612 DEFUN (no_set_originator_id,
3613 no_set_originator_id_cmd,
3614 "no set originator-id",
3615 NO_STR
3616 SET_STR
3617 "BGP originator ID attribute\n")
3618 {
3619 if (argc == 0)
3620 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3621
3622 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3623 }
3624
3625 ALIAS (no_set_originator_id,
3626 no_set_originator_id_val_cmd,
3627 "no set originator-id A.B.C.D",
3628 NO_STR
3629 SET_STR
3630 "BGP originator ID attribute\n"
3631 "IP address of originator\n")
3632
3633 DEFUN (set_pathlimit_ttl,
3634 set_pathlimit_ttl_cmd,
3635 "set pathlimit ttl <1-255>",
3636 SET_STR
3637 "BGP AS-Pathlimit attribute\n"
3638 "Set AS-Path Hop-count TTL\n")
3639 {
3640 return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]);
3641 }
3642
3643 DEFUN (no_set_pathlimit_ttl,
3644 no_set_pathlimit_ttl_cmd,
3645 "no set pathlimit ttl",
3646 NO_STR
3647 SET_STR
3648 "BGP AS-Pathlimit attribute\n"
3649 "Set AS-Path Hop-count TTL\n")
3650 {
3651 if (argc == 0)
3652 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL);
3653
3654 return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]);
3655 }
3656
3657 ALIAS (no_set_pathlimit_ttl,
3658 no_set_pathlimit_ttl_val_cmd,
3659 "no set pathlimit ttl <1-255>",
3660 NO_STR
3661 MATCH_STR
3662 "BGP AS-Pathlimit attribute\n"
3663 "Set AS-Path Hop-count TTL\n")
3664
3665 DEFUN (match_pathlimit_as,
3666 match_pathlimit_as_cmd,
3667 "match pathlimit as <1-65535>",
3668 MATCH_STR
3669 "BGP AS-Pathlimit attribute\n"
3670 "Match Pathlimit AS number\n")
3671 {
3672 return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]);
3673 }
3674
3675 DEFUN (no_match_pathlimit_as,
3676 no_match_pathlimit_as_cmd,
3677 "no match pathlimit as",
3678 NO_STR
3679 MATCH_STR
3680 "BGP AS-Pathlimit attribute\n"
3681 "Match Pathlimit AS number\n")
3682 {
3683 if (argc == 0)
3684 return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL);
3685
3686 return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]);
3687 }
3688
3689 ALIAS (no_match_pathlimit_as,
3690 no_match_pathlimit_as_val_cmd,
3691 "no match pathlimit as <1-65535>",
3692 NO_STR
3693 MATCH_STR
3694 "BGP AS-Pathlimit attribute\n"
3695 "Match Pathlimit ASN\n")
3696
3697 \f
3698 /* Initialization of route map. */
3699 void
3700 bgp_route_map_init (void)
3701 {
3702 route_map_init ();
3703 route_map_init_vty ();
3704 route_map_add_hook (bgp_route_map_update);
3705 route_map_delete_hook (bgp_route_map_update);
3706
3707 route_map_install_match (&route_match_peer_cmd);
3708 route_map_install_match (&route_match_ip_address_cmd);
3709 route_map_install_match (&route_match_ip_next_hop_cmd);
3710 route_map_install_match (&route_match_ip_route_source_cmd);
3711 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3712 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
3713 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
3714 route_map_install_match (&route_match_aspath_cmd);
3715 route_map_install_match (&route_match_community_cmd);
3716 route_map_install_match (&route_match_ecommunity_cmd);
3717 route_map_install_match (&route_match_metric_cmd);
3718 route_map_install_match (&route_match_origin_cmd);
3719
3720 route_map_install_set (&route_set_ip_nexthop_cmd);
3721 route_map_install_set (&route_set_local_pref_cmd);
3722 route_map_install_set (&route_set_weight_cmd);
3723 route_map_install_set (&route_set_metric_cmd);
3724 route_map_install_set (&route_set_aspath_prepend_cmd);
3725 route_map_install_set (&route_set_origin_cmd);
3726 route_map_install_set (&route_set_atomic_aggregate_cmd);
3727 route_map_install_set (&route_set_aggregator_as_cmd);
3728 route_map_install_set (&route_set_community_cmd);
3729 route_map_install_set (&route_set_community_delete_cmd);
3730 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3731 route_map_install_set (&route_set_originator_id_cmd);
3732 route_map_install_set (&route_set_ecommunity_rt_cmd);
3733 route_map_install_set (&route_set_ecommunity_soo_cmd);
3734
3735 install_element (RMAP_NODE, &match_peer_cmd);
3736 install_element (RMAP_NODE, &match_peer_local_cmd);
3737 install_element (RMAP_NODE, &no_match_peer_cmd);
3738 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3739 install_element (RMAP_NODE, &no_match_peer_local_cmd);
3740 install_element (RMAP_NODE, &match_ip_address_cmd);
3741 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3742 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3743 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3744 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3745 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
3746 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3747 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3748 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
3749
3750 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3751 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3752 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3753 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3754 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3755 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
3756 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3757 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3758 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
3759
3760 install_element (RMAP_NODE, &match_aspath_cmd);
3761 install_element (RMAP_NODE, &no_match_aspath_cmd);
3762 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3763 install_element (RMAP_NODE, &match_metric_cmd);
3764 install_element (RMAP_NODE, &no_match_metric_cmd);
3765 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3766 install_element (RMAP_NODE, &match_community_cmd);
3767 install_element (RMAP_NODE, &match_community_exact_cmd);
3768 install_element (RMAP_NODE, &no_match_community_cmd);
3769 install_element (RMAP_NODE, &no_match_community_val_cmd);
3770 install_element (RMAP_NODE, &no_match_community_exact_cmd);
3771 install_element (RMAP_NODE, &match_ecommunity_cmd);
3772 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3773 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
3774 install_element (RMAP_NODE, &match_origin_cmd);
3775 install_element (RMAP_NODE, &no_match_origin_cmd);
3776 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3777
3778 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
3779 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
3780 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3781 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3782 install_element (RMAP_NODE, &set_local_pref_cmd);
3783 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3784 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3785 install_element (RMAP_NODE, &set_weight_cmd);
3786 install_element (RMAP_NODE, &no_set_weight_cmd);
3787 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3788 install_element (RMAP_NODE, &set_metric_cmd);
3789 install_element (RMAP_NODE, &set_metric_addsub_cmd);
3790 install_element (RMAP_NODE, &no_set_metric_cmd);
3791 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3792 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3793 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3794 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3795 install_element (RMAP_NODE, &set_origin_cmd);
3796 install_element (RMAP_NODE, &no_set_origin_cmd);
3797 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3798 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3799 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3800 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3801 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3802 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3803 install_element (RMAP_NODE, &set_community_cmd);
3804 install_element (RMAP_NODE, &set_community_none_cmd);
3805 install_element (RMAP_NODE, &no_set_community_cmd);
3806 install_element (RMAP_NODE, &no_set_community_val_cmd);
3807 install_element (RMAP_NODE, &no_set_community_none_cmd);
3808 install_element (RMAP_NODE, &set_community_delete_cmd);
3809 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3810 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3811 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3812 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3813 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3814 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3815 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3816 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3817 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3818 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3819 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3820 install_element (RMAP_NODE, &set_originator_id_cmd);
3821 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3822 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3823
3824 #ifdef HAVE_IPV6
3825 route_map_install_match (&route_match_ipv6_address_cmd);
3826 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3827 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3828 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3829 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3830
3831 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3832 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3833 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3834 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3835 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3836 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3837 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3838 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3839 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3840 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3841 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3842 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3843 #endif /* HAVE_IPV6 */
3844
3845 /* AS-Pathlimit */
3846 route_map_install_match (&route_match_pathlimit_as_cmd);
3847 route_map_install_set (&route_set_pathlimit_ttl_cmd);
3848
3849 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3850 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3851 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3852 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3853 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3854 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
3855 }