1 /* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
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
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.
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
31 #ifdef HAVE_LIBPCREPOSIX
32 # include <pcreposix.h>
34 # ifdef HAVE_GNU_REGEX
37 # include "regex-gnu.h"
38 # endif /* HAVE_GNU_REGEX */
39 #endif /* HAVE_LIBPCREPOSIX */
41 #include "sockunion.h"
45 #include "bgpd/bgpd.h"
46 #include "bgpd/bgp_table.h"
47 #include "bgpd/bgp_attr.h"
48 #include "bgpd/bgp_aspath.h"
49 #include "bgpd/bgp_packet.h"
50 #include "bgpd/bgp_route.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_regex.h"
53 #include "bgpd/bgp_community.h"
54 #include "bgpd/bgp_clist.h"
55 #include "bgpd/bgp_filter.h"
56 #include "bgpd/bgp_mplsvpn.h"
57 #include "bgpd/bgp_ecommunity.h"
58 #include "bgpd/bgp_vty.h"
59 #include "bgpd/bgp_debug.h"
62 /* Memo of route-map commands.
71 ip route-source : Done
75 ipv6 route-source: (This will not be implemented by bgpd)
76 ipv6 prefix-list : Done
77 length : (This will not be implemented by bgpd)
79 route-type : (This will not be implemented by bgpd)
81 local-preference : Done
83 set as-path prepend : Done
85 automatic-tag : (This will not be implemented by bgpd)
89 default : (This will not be implemented by bgpd)
90 interface : (This will not be implemented by bgpd)
91 ip default : (This will not be implemented by bgpd)
93 ip precedence : (This will not be implemented by bgpd)
94 ip tos : (This will not be implemented by bgpd)
95 level : (This will not be implemented by bgpd)
96 local-preference : Done
105 set ipv6 next-hop global: Done
106 set ipv6 next-hop prefer-global: Done
107 set ipv6 next-hop local : Done
108 set as-path exclude : Done
112 /* generic value manipulation to be shared in multiple rules */
114 #define RMAP_VALUE_SET 0
115 #define RMAP_VALUE_ADD 1
116 #define RMAP_VALUE_SUB 2
126 route_value_match (struct rmap_value
*rv
, u_int32_t value
)
128 if (rv
->variable
== 0 && value
== rv
->value
)
135 route_value_adjust (struct rmap_value
*rv
, u_int32_t current
, struct peer
*peer
)
139 switch (rv
->variable
)
152 if (current
> UINT32_MAX
-value
)
154 return current
+ value
;
156 if (current
<= value
)
158 return current
- value
;
165 route_value_compile (const char *arg
)
167 u_int8_t action
= RMAP_VALUE_SET
, var
= 0;
168 unsigned long larg
= 0;
170 struct rmap_value
*rv
;
174 action
= RMAP_VALUE_ADD
;
177 else if (arg
[0] == '-')
179 action
= RMAP_VALUE_SUB
;
186 larg
= strtoul (arg
, &endptr
, 10);
187 if (*arg
== 0 || *endptr
!= 0 || errno
|| larg
> UINT32_MAX
)
192 if (strcmp(arg
, "rtt") == 0)
198 rv
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_value
));
209 route_value_free (void *rule
)
211 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
214 /* generic as path object to be shared in multiple rules */
217 route_aspath_compile (const char *arg
)
219 struct aspath
*aspath
;
221 aspath
= aspath_str2aspath (arg
);
228 route_aspath_free (void *rule
)
230 struct aspath
*aspath
= rule
;
231 aspath_free (aspath
);
234 /* 'match peer (A.B.C.D|X:X::X:X)' */
236 /* Compares the peer specified in the 'match peer' clause with the peer
237 received in bgp_info->peer. If it is the same, or if the peer structure
238 received is a peer_group containing it, returns RMAP_MATCH. */
239 static route_map_result_t
240 route_match_peer (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
244 union sockunion su_def
= { .sin
= { .sin_family
= AF_INET
,
245 .sin_addr
.s_addr
= INADDR_ANY
} };
246 struct peer_group
*group
;
248 struct listnode
*node
, *nnode
;
250 if (type
== RMAP_BGP
)
253 peer
= ((struct bgp_info
*) object
)->peer
;
255 if ( ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
) &&
256 ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_EXPORT
) )
259 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
260 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
261 if (sockunion_same (su
, &su_def
))
264 if ( CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_NETWORK
) ||
265 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
) ||
266 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_DEFAULT
))
273 if (! CHECK_FLAG (peer
->sflags
, PEER_STATUS_GROUP
))
275 if (sockunion_same (su
, &peer
->su
))
283 for (ALL_LIST_ELEMENTS (group
->peer
, node
, nnode
, peer
))
285 if (sockunion_same (su
, &peer
->su
))
295 route_match_peer_compile (const char *arg
)
300 su
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union sockunion
));
302 ret
= str2sockunion (strcmp(arg
, "local") ? arg
: "0.0.0.0", su
);
304 XFREE (MTYPE_ROUTE_MAP_COMPILED
, su
);
311 /* Free route map's compiled `ip address' value. */
313 route_match_peer_free (void *rule
)
315 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
318 /* Route map commands for ip address matching. */
319 struct route_map_rule_cmd route_match_peer_cmd
=
323 route_match_peer_compile
,
324 route_match_peer_free
327 /* `match ip address IP_ACCESS_LIST' */
329 /* Match function should return 1 if match is success else return
331 static route_map_result_t
332 route_match_ip_address (void *rule
, struct prefix
*prefix
,
333 route_map_object_t type
, void *object
)
335 struct access_list
*alist
;
336 /* struct prefix_ipv4 match; */
338 if (type
== RMAP_BGP
)
340 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
344 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
345 RMAP_NOMATCH
: RMAP_MATCH
);
350 /* Route map `ip address' match statement. `arg' should be
353 route_match_ip_address_compile (const char *arg
)
355 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
358 /* Free route map's compiled `ip address' value. */
360 route_match_ip_address_free (void *rule
)
362 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
365 /* Route map commands for ip address matching. */
366 struct route_map_rule_cmd route_match_ip_address_cmd
=
369 route_match_ip_address
,
370 route_match_ip_address_compile
,
371 route_match_ip_address_free
374 /* `match ip next-hop IP_ADDRESS' */
376 /* Match function return 1 if match is success else return zero. */
377 static route_map_result_t
378 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
379 route_map_object_t type
, void *object
)
381 struct access_list
*alist
;
382 struct bgp_info
*bgp_info
;
383 struct prefix_ipv4 p
;
385 if (type
== RMAP_BGP
)
389 p
.prefix
= bgp_info
->attr
->nexthop
;
390 p
.prefixlen
= IPV4_MAX_BITLEN
;
392 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
396 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
397 RMAP_NOMATCH
: RMAP_MATCH
);
402 /* Route map `ip next-hop' match statement. `arg' is
405 route_match_ip_next_hop_compile (const char *arg
)
407 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
410 /* Free route map's compiled `ip address' value. */
412 route_match_ip_next_hop_free (void *rule
)
414 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
417 /* Route map commands for ip next-hop matching. */
418 struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
421 route_match_ip_next_hop
,
422 route_match_ip_next_hop_compile
,
423 route_match_ip_next_hop_free
426 /* `match ip route-source ACCESS-LIST' */
428 /* Match function return 1 if match is success else return zero. */
429 static route_map_result_t
430 route_match_ip_route_source (void *rule
, struct prefix
*prefix
,
431 route_map_object_t type
, void *object
)
433 struct access_list
*alist
;
434 struct bgp_info
*bgp_info
;
436 struct prefix_ipv4 p
;
438 if (type
== RMAP_BGP
)
441 peer
= bgp_info
->peer
;
443 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
447 p
.prefix
= peer
->su
.sin
.sin_addr
;
448 p
.prefixlen
= IPV4_MAX_BITLEN
;
450 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
454 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
455 RMAP_NOMATCH
: RMAP_MATCH
);
460 /* Route map `ip route-source' match statement. `arg' is
463 route_match_ip_route_source_compile (const char *arg
)
465 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
468 /* Free route map's compiled `ip address' value. */
470 route_match_ip_route_source_free (void *rule
)
472 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
475 /* Route map commands for ip route-source matching. */
476 struct route_map_rule_cmd route_match_ip_route_source_cmd
=
479 route_match_ip_route_source
,
480 route_match_ip_route_source_compile
,
481 route_match_ip_route_source_free
484 /* `match ip address prefix-list PREFIX_LIST' */
486 static route_map_result_t
487 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
488 route_map_object_t type
, void *object
)
490 struct prefix_list
*plist
;
492 if (type
== RMAP_BGP
)
494 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
498 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
499 RMAP_NOMATCH
: RMAP_MATCH
);
505 route_match_ip_address_prefix_list_compile (const char *arg
)
507 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
511 route_match_ip_address_prefix_list_free (void *rule
)
513 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
516 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
518 "ip address prefix-list",
519 route_match_ip_address_prefix_list
,
520 route_match_ip_address_prefix_list_compile
,
521 route_match_ip_address_prefix_list_free
524 /* `match ip next-hop prefix-list PREFIX_LIST' */
526 static route_map_result_t
527 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
528 route_map_object_t type
, void *object
)
530 struct prefix_list
*plist
;
531 struct bgp_info
*bgp_info
;
532 struct prefix_ipv4 p
;
534 if (type
== RMAP_BGP
)
538 p
.prefix
= bgp_info
->attr
->nexthop
;
539 p
.prefixlen
= IPV4_MAX_BITLEN
;
541 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
545 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
546 RMAP_NOMATCH
: RMAP_MATCH
);
552 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
554 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
558 route_match_ip_next_hop_prefix_list_free (void *rule
)
560 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
563 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
565 "ip next-hop prefix-list",
566 route_match_ip_next_hop_prefix_list
,
567 route_match_ip_next_hop_prefix_list_compile
,
568 route_match_ip_next_hop_prefix_list_free
571 /* `match ip route-source prefix-list PREFIX_LIST' */
573 static route_map_result_t
574 route_match_ip_route_source_prefix_list (void *rule
, struct prefix
*prefix
,
575 route_map_object_t type
, void *object
)
577 struct prefix_list
*plist
;
578 struct bgp_info
*bgp_info
;
580 struct prefix_ipv4 p
;
582 if (type
== RMAP_BGP
)
585 peer
= bgp_info
->peer
;
587 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
591 p
.prefix
= peer
->su
.sin
.sin_addr
;
592 p
.prefixlen
= IPV4_MAX_BITLEN
;
594 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
598 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
599 RMAP_NOMATCH
: RMAP_MATCH
);
605 route_match_ip_route_source_prefix_list_compile (const char *arg
)
607 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
611 route_match_ip_route_source_prefix_list_free (void *rule
)
613 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
616 struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd
=
618 "ip route-source prefix-list",
619 route_match_ip_route_source_prefix_list
,
620 route_match_ip_route_source_prefix_list_compile
,
621 route_match_ip_route_source_prefix_list_free
624 /* `match local-preference LOCAL-PREF' */
626 /* Match function return 1 if match is success else return zero. */
627 static route_map_result_t
628 route_match_local_pref (void *rule
, struct prefix
*prefix
,
629 route_map_object_t type
, void *object
)
631 u_int32_t
*local_pref
;
632 struct bgp_info
*bgp_info
;
634 if (type
== RMAP_BGP
)
639 if (bgp_info
->attr
->local_pref
== *local_pref
)
647 /* Route map `match local-preference' match statement.
648 `arg' is local-pref value */
650 route_match_local_pref_compile (const char *arg
)
652 u_int32_t
*local_pref
;
654 unsigned long tmpval
;
656 /* Locpref value shoud be integer. */
657 if (! all_digit (arg
))
661 tmpval
= strtoul (arg
, &endptr
, 10);
662 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
665 local_pref
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
670 *local_pref
= tmpval
;
674 /* Free route map's compiled `match local-preference' value. */
676 route_match_local_pref_free (void *rule
)
678 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
681 /* Route map commands for metric matching. */
682 struct route_map_rule_cmd route_match_local_pref_cmd
=
685 route_match_local_pref
,
686 route_match_local_pref_compile
,
687 route_match_local_pref_free
690 /* `match metric METRIC' */
692 /* Match function return 1 if match is success else return zero. */
693 static route_map_result_t
694 route_match_metric (void *rule
, struct prefix
*prefix
,
695 route_map_object_t type
, void *object
)
697 struct rmap_value
*rv
;
698 struct bgp_info
*bgp_info
;
700 if (type
== RMAP_BGP
)
704 return route_value_match(rv
, bgp_info
->attr
->med
);
709 /* Route map commands for metric matching. */
710 struct route_map_rule_cmd route_match_metric_cmd
=
718 /* `match as-path ASPATH' */
720 /* Match function for as-path match. I assume given object is */
721 static route_map_result_t
722 route_match_aspath (void *rule
, struct prefix
*prefix
,
723 route_map_object_t type
, void *object
)
726 struct as_list
*as_list
;
727 struct bgp_info
*bgp_info
;
729 if (type
== RMAP_BGP
)
731 as_list
= as_list_lookup ((char *) rule
);
738 return ((as_list_apply (as_list
, bgp_info
->attr
->aspath
) == AS_FILTER_DENY
) ? RMAP_NOMATCH
: RMAP_MATCH
);
743 /* Compile function for as-path match. */
745 route_match_aspath_compile (const char *arg
)
747 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
750 /* Compile function for as-path match. */
752 route_match_aspath_free (void *rule
)
754 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
757 /* Route map commands for aspath matching. */
758 struct route_map_rule_cmd route_match_aspath_cmd
=
762 route_match_aspath_compile
,
763 route_match_aspath_free
766 /* `match community COMMUNIY' */
767 struct rmap_community
773 /* Match function for community match. */
774 static route_map_result_t
775 route_match_community (void *rule
, struct prefix
*prefix
,
776 route_map_object_t type
, void *object
)
778 struct community_list
*list
;
779 struct bgp_info
*bgp_info
;
780 struct rmap_community
*rcom
;
782 if (type
== RMAP_BGP
)
787 list
= community_list_lookup (bgp_clist
, rcom
->name
, COMMUNITY_LIST_MASTER
);
793 if (community_list_exact_match (bgp_info
->attr
->community
, list
))
798 if (community_list_match (bgp_info
->attr
->community
, list
))
805 /* Compile function for community match. */
807 route_match_community_compile (const char *arg
)
809 struct rmap_community
*rcom
;
813 rcom
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_community
));
815 p
= strchr (arg
, ' ');
819 rcom
->name
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
820 memcpy (rcom
->name
, arg
, len
);
825 rcom
->name
= XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
831 /* Compile function for community match. */
833 route_match_community_free (void *rule
)
835 struct rmap_community
*rcom
= rule
;
837 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
838 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
);
841 /* Route map commands for community matching. */
842 struct route_map_rule_cmd route_match_community_cmd
=
845 route_match_community
,
846 route_match_community_compile
,
847 route_match_community_free
850 /* Match function for extcommunity match. */
851 static route_map_result_t
852 route_match_ecommunity (void *rule
, struct prefix
*prefix
,
853 route_map_object_t type
, void *object
)
855 struct community_list
*list
;
856 struct bgp_info
*bgp_info
;
858 if (type
== RMAP_BGP
)
862 if (!bgp_info
->attr
->extra
)
865 list
= community_list_lookup (bgp_clist
, (char *) rule
,
866 EXTCOMMUNITY_LIST_MASTER
);
870 if (ecommunity_list_match (bgp_info
->attr
->extra
->ecommunity
, list
))
876 /* Compile function for extcommunity match. */
878 route_match_ecommunity_compile (const char *arg
)
880 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
883 /* Compile function for extcommunity match. */
885 route_match_ecommunity_free (void *rule
)
887 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
890 /* Route map commands for community matching. */
891 struct route_map_rule_cmd route_match_ecommunity_cmd
=
894 route_match_ecommunity
,
895 route_match_ecommunity_compile
,
896 route_match_ecommunity_free
899 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
900 and `address-family vpnv4'. */
903 static route_map_result_t
904 route_match_origin (void *rule
, struct prefix
*prefix
,
905 route_map_object_t type
, void *object
)
908 struct bgp_info
*bgp_info
;
910 if (type
== RMAP_BGP
)
915 if (bgp_info
->attr
->origin
== *origin
)
923 route_match_origin_compile (const char *arg
)
927 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
929 if (strcmp (arg
, "igp") == 0)
931 else if (strcmp (arg
, "egp") == 0)
939 /* Free route map's compiled `ip address' value. */
941 route_match_origin_free (void *rule
)
943 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
946 /* Route map commands for origin matching. */
947 struct route_map_rule_cmd route_match_origin_cmd
=
951 route_match_origin_compile
,
952 route_match_origin_free
955 /* match probability { */
957 static route_map_result_t
958 route_match_probability (void *rule
, struct prefix
*prefix
,
959 route_map_object_t type
, void *object
)
963 switch (*(long *) rule
)
966 case RAND_MAX
: return RMAP_MATCH
;
968 if (r
< *(long *) rule
)
978 route_match_probability_compile (const char *arg
)
984 lobule
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (long));
988 case 0: *lobule
= 0; break;
989 case 100: *lobule
= RAND_MAX
; break;
990 default: *lobule
= RAND_MAX
/ 100 * perc
;
997 route_match_probability_free (void *rule
)
999 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1002 struct route_map_rule_cmd route_match_probability_cmd
=
1005 route_match_probability
,
1006 route_match_probability_compile
,
1007 route_match_probability_free
1010 /* `match interface IFNAME' */
1011 /* Match function should return 1 if match is success else return
1013 static route_map_result_t
1014 route_match_interface (void *rule
, struct prefix
*prefix
,
1015 route_map_object_t type
, void *object
)
1017 struct interface
*ifp
;
1018 struct bgp_info
*info
;
1020 if (type
== RMAP_BGP
)
1024 if (!info
|| !info
->attr
)
1025 return RMAP_NOMATCH
;
1027 ifp
= if_lookup_by_name_all_vrf ((char *)rule
);
1029 if (ifp
== NULL
|| ifp
->ifindex
!= info
->attr
->nh_ifindex
)
1030 return RMAP_NOMATCH
;
1034 return RMAP_NOMATCH
;
1037 /* Route map `interface' match statement. `arg' should be
1040 route_match_interface_compile (const char *arg
)
1042 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1045 /* Free route map's compiled `interface' value. */
1047 route_match_interface_free (void *rule
)
1049 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1052 /* Route map commands for ip address matching. */
1053 struct route_map_rule_cmd route_match_interface_cmd
=
1056 route_match_interface
,
1057 route_match_interface_compile
,
1058 route_match_interface_free
1063 /* `set ip next-hop IP_ADDRESS' */
1065 /* Match function return 1 if match is success else return zero. */
1066 static route_map_result_t
1067 route_match_tag (void *rule
, struct prefix
*prefix
,
1068 route_map_object_t type
, void *object
)
1071 struct bgp_info
*bgp_info
;
1073 if (type
== RMAP_BGP
)
1078 if (!bgp_info
->attr
->extra
)
1079 return RMAP_NOMATCH
;
1081 return ((bgp_info
->attr
->extra
->tag
== *tag
)? RMAP_MATCH
: RMAP_NOMATCH
);
1084 return RMAP_NOMATCH
;
1088 /* Route map `match tag' match statement. `arg' is TAG value */
1090 route_match_tag_compile (const char *arg
)
1095 /* tag value shoud be integer. */
1096 if (! all_digit (arg
))
1103 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
1114 /* Free route map's compiled 'match tag' value. */
1116 route_match_tag_free (void *rule
)
1118 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1121 /* Route map commands for tag matching. */
1122 struct route_map_rule_cmd route_match_tag_cmd
=
1126 route_match_tag_compile
,
1127 route_match_tag_free
,
1131 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1132 struct rmap_ip_nexthop_set
1134 struct in_addr
*address
;
1139 static route_map_result_t
1140 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
1141 route_map_object_t type
, void *object
)
1143 struct rmap_ip_nexthop_set
*rins
= rule
;
1144 struct bgp_info
*bgp_info
;
1147 if (type
== RMAP_BGP
)
1150 peer
= bgp_info
->peer
;
1152 if (rins
->unchanged
)
1154 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1155 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1157 else if (rins
->peer_address
)
1159 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
1160 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1162 && sockunion_family (peer
->su_remote
) == AF_INET
)
1164 bgp_info
->attr
->nexthop
.s_addr
= sockunion2ip (peer
->su_remote
);
1165 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1167 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
1169 /* The next hop value will be set as part of packet rewrite.
1170 * Set the flags here to indicate that rewrite needs to be done.
1171 * Also, clear the value.
1173 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1174 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1175 bgp_info
->attr
->nexthop
.s_addr
= 0;
1180 /* Set next hop value. */
1181 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1182 bgp_info
->attr
->nexthop
= *rins
->address
;
1183 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1184 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1191 /* Route map `ip nexthop' compile function. Given string is converted
1192 to struct in_addr structure. */
1194 route_set_ip_nexthop_compile (const char *arg
)
1196 struct rmap_ip_nexthop_set
*rins
;
1197 struct in_addr
*address
= NULL
;
1198 int peer_address
= 0;
1202 if (strcmp (arg
, "peer-address") == 0)
1204 else if (strcmp (arg
, "unchanged") == 0)
1208 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
1209 ret
= inet_aton (arg
, address
);
1213 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
1218 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_ip_nexthop_set
));
1220 rins
->address
= address
;
1221 rins
->peer_address
= peer_address
;
1222 rins
->unchanged
= unchanged
;
1227 /* Free route map's compiled `ip nexthop' value. */
1229 route_set_ip_nexthop_free (void *rule
)
1231 struct rmap_ip_nexthop_set
*rins
= rule
;
1234 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1236 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
);
1239 /* Route map commands for ip nexthop set. */
1240 struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
1243 route_set_ip_nexthop
,
1244 route_set_ip_nexthop_compile
,
1245 route_set_ip_nexthop_free
1248 /* `set local-preference LOCAL_PREF' */
1250 /* Set local preference. */
1251 static route_map_result_t
1252 route_set_local_pref (void *rule
, struct prefix
*prefix
,
1253 route_map_object_t type
, void *object
)
1255 struct rmap_value
*rv
;
1256 struct bgp_info
*bgp_info
;
1257 u_int32_t locpref
= 0;
1259 if (type
== RMAP_BGP
)
1261 /* Fetch routemap's rule information. */
1265 /* Set local preference value. */
1266 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
1267 locpref
= bgp_info
->attr
->local_pref
;
1269 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1270 bgp_info
->attr
->local_pref
= route_value_adjust(rv
, locpref
, bgp_info
->peer
);
1276 /* Set local preference rule structure. */
1277 struct route_map_rule_cmd route_set_local_pref_cmd
=
1280 route_set_local_pref
,
1281 route_value_compile
,
1285 /* `set weight WEIGHT' */
1288 static route_map_result_t
1289 route_set_weight (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
1292 struct rmap_value
*rv
;
1293 struct bgp_info
*bgp_info
;
1296 if (type
== RMAP_BGP
)
1298 /* Fetch routemap's rule information. */
1302 /* Set weight value. */
1303 weight
= route_value_adjust(rv
, 0, bgp_info
->peer
);
1305 (bgp_attr_extra_get (bgp_info
->attr
))->weight
= weight
;
1306 else if (bgp_info
->attr
->extra
)
1307 bgp_info
->attr
->extra
->weight
= 0;
1313 /* Set local preference rule structure. */
1314 struct route_map_rule_cmd route_set_weight_cmd
=
1318 route_value_compile
,
1322 /* `set metric METRIC' */
1324 /* Set metric to attribute. */
1325 static route_map_result_t
1326 route_set_metric (void *rule
, struct prefix
*prefix
,
1327 route_map_object_t type
, void *object
)
1329 struct rmap_value
*rv
;
1330 struct bgp_info
*bgp_info
;
1333 if (type
== RMAP_BGP
)
1335 /* Fetch routemap's rule information. */
1339 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1340 med
= bgp_info
->attr
->med
;
1342 bgp_info
->attr
->med
= route_value_adjust(rv
, med
, bgp_info
->peer
);
1343 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
1348 /* Set metric rule structure. */
1349 struct route_map_rule_cmd route_set_metric_cmd
=
1353 route_value_compile
,
1357 /* `set as-path prepend ASPATH' */
1359 /* For AS path prepend mechanism. */
1360 static route_map_result_t
1361 route_set_aspath_prepend (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1363 struct aspath
*aspath
;
1365 struct bgp_info
*binfo
;
1367 if (type
== RMAP_BGP
)
1371 if (binfo
->attr
->aspath
->refcnt
)
1372 new = aspath_dup (binfo
->attr
->aspath
);
1374 new = binfo
->attr
->aspath
;
1376 if ((uintptr_t)rule
> 10)
1379 aspath_prepend (aspath
, new);
1383 as_t as
= aspath_leftmost(new);
1384 if (!as
) as
= binfo
->peer
->as
;
1385 new = aspath_add_seq_n (new, as
, (uintptr_t) rule
);
1388 binfo
->attr
->aspath
= new;
1395 route_set_aspath_prepend_compile (const char *arg
)
1399 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
< 10)
1400 return (void*)(uintptr_t)num
;
1402 return route_aspath_compile(arg
);
1406 route_set_aspath_prepend_free (void *rule
)
1408 if ((uintptr_t)rule
> 10)
1409 route_aspath_free(rule
);
1413 /* Set as-path prepend rule structure. */
1414 struct route_map_rule_cmd route_set_aspath_prepend_cmd
=
1417 route_set_aspath_prepend
,
1418 route_set_aspath_prepend_compile
,
1419 route_set_aspath_prepend_free
,
1422 /* `set as-path exclude ASn' */
1424 /* For ASN exclude mechanism.
1425 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1426 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1428 static route_map_result_t
1429 route_set_aspath_exclude (void *rule
, struct prefix
*dummy
, route_map_object_t type
, void *object
)
1431 struct aspath
* new_path
, * exclude_path
;
1432 struct bgp_info
*binfo
;
1434 if (type
== RMAP_BGP
)
1436 exclude_path
= rule
;
1438 if (binfo
->attr
->aspath
->refcnt
)
1439 new_path
= aspath_dup (binfo
->attr
->aspath
);
1441 new_path
= binfo
->attr
->aspath
;
1442 binfo
->attr
->aspath
= aspath_filter_exclude (new_path
, exclude_path
);
1447 /* Set ASn exlude rule structure. */
1448 struct route_map_rule_cmd route_set_aspath_exclude_cmd
=
1451 route_set_aspath_exclude
,
1452 route_aspath_compile
,
1456 /* `set community COMMUNITY' */
1459 struct community
*com
;
1464 /* For community set mechanism. */
1465 static route_map_result_t
1466 route_set_community (void *rule
, struct prefix
*prefix
,
1467 route_map_object_t type
, void *object
)
1469 struct rmap_com_set
*rcs
;
1470 struct bgp_info
*binfo
;
1472 struct community
*new = NULL
;
1473 struct community
*old
;
1474 struct community
*merge
;
1476 if (type
== RMAP_BGP
)
1481 old
= attr
->community
;
1486 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
));
1487 attr
->community
= NULL
;
1488 /* See the longer comment down below. */
1489 if (old
&& old
->refcnt
== 0)
1490 community_free(old
);
1494 /* "additive" case. */
1495 if (rcs
->additive
&& old
)
1497 merge
= community_merge (community_dup (old
), rcs
->com
);
1499 /* HACK: if the old community is not intern'd,
1500 * we should free it here, or all reference to it may be lost.
1501 * Really need to cleanup attribute caching sometime.
1503 if (old
->refcnt
== 0)
1504 community_free (old
);
1505 new = community_uniq_sort (merge
);
1506 community_free (merge
);
1509 new = community_dup (rcs
->com
);
1511 /* will be interned by caller if required */
1512 attr
->community
= new;
1514 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1520 /* Compile function for set community. */
1522 route_set_community_compile (const char *arg
)
1524 struct rmap_com_set
*rcs
;
1525 struct community
*com
= NULL
;
1530 if (strcmp (arg
, "none") == 0)
1534 sp
= strstr (arg
, "additive");
1538 /* "additive" keyworkd is included. */
1543 com
= community_str2com (arg
);
1552 rcs
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_com_set
));
1554 rcs
->additive
= additive
;
1560 /* Free function for set community. */
1562 route_set_community_free (void *rule
)
1564 struct rmap_com_set
*rcs
= rule
;
1567 community_free (rcs
->com
);
1568 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1571 /* Set community rule structure. */
1572 struct route_map_rule_cmd route_set_community_cmd
=
1575 route_set_community
,
1576 route_set_community_compile
,
1577 route_set_community_free
,
1580 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
1582 /* For community set mechanism. */
1583 static route_map_result_t
1584 route_set_community_delete (void *rule
, struct prefix
*prefix
,
1585 route_map_object_t type
, void *object
)
1587 struct community_list
*list
;
1588 struct community
*merge
;
1589 struct community
*new;
1590 struct community
*old
;
1591 struct bgp_info
*binfo
;
1593 if (type
== RMAP_BGP
)
1599 list
= community_list_lookup (bgp_clist
, rule
, COMMUNITY_LIST_MASTER
);
1600 old
= binfo
->attr
->community
;
1604 merge
= community_list_match_delete (community_dup (old
), list
);
1605 new = community_uniq_sort (merge
);
1606 community_free (merge
);
1608 /* HACK: if the old community is not intern'd,
1609 * we should free it here, or all reference to it may be lost.
1610 * Really need to cleanup attribute caching sometime.
1612 if (old
->refcnt
== 0)
1613 community_free (old
);
1617 binfo
->attr
->community
= NULL
;
1618 binfo
->attr
->flag
&= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1619 community_free (new);
1623 binfo
->attr
->community
= new;
1624 binfo
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1632 /* Compile function for set community. */
1634 route_set_community_delete_compile (const char *arg
)
1640 p
= strchr (arg
, ' ');
1644 str
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1645 memcpy (str
, arg
, len
);
1653 /* Free function for set community. */
1655 route_set_community_delete_free (void *rule
)
1657 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1660 /* Set community rule structure. */
1661 struct route_map_rule_cmd route_set_community_delete_cmd
=
1664 route_set_community_delete
,
1665 route_set_community_delete_compile
,
1666 route_set_community_delete_free
,
1669 /* `set extcommunity rt COMMUNITY' */
1671 /* For community set mechanism. Used by _rt and _soo. */
1672 static route_map_result_t
1673 route_set_ecommunity (void *rule
, struct prefix
*prefix
,
1674 route_map_object_t type
, void *object
)
1676 struct ecommunity
*ecom
;
1677 struct ecommunity
*new_ecom
;
1678 struct ecommunity
*old_ecom
;
1679 struct bgp_info
*bgp_info
;
1681 if (type
== RMAP_BGP
)
1689 /* We assume additive for Extended Community. */
1690 old_ecom
= (bgp_attr_extra_get (bgp_info
->attr
))->ecommunity
;
1694 new_ecom
= ecommunity_merge (ecommunity_dup (old_ecom
), ecom
);
1696 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1697 * ->refcnt = 0 => set by a previous route-map statement */
1698 if (!old_ecom
->refcnt
)
1699 ecommunity_free (&old_ecom
);
1702 new_ecom
= ecommunity_dup (ecom
);
1704 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1705 bgp_info
->attr
->extra
->ecommunity
= new_ecom
;
1707 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
);
1712 /* Compile function for set community. */
1714 route_set_ecommunity_rt_compile (const char *arg
)
1716 struct ecommunity
*ecom
;
1718 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
1721 return ecommunity_intern (ecom
);
1724 /* Free function for set community. Used by _rt and _soo */
1726 route_set_ecommunity_free (void *rule
)
1728 struct ecommunity
*ecom
= rule
;
1729 ecommunity_unintern (&ecom
);
1732 /* Set community rule structure. */
1733 struct route_map_rule_cmd route_set_ecommunity_rt_cmd
=
1736 route_set_ecommunity
,
1737 route_set_ecommunity_rt_compile
,
1738 route_set_ecommunity_free
,
1741 /* `set extcommunity soo COMMUNITY' */
1743 /* Compile function for set community. */
1745 route_set_ecommunity_soo_compile (const char *arg
)
1747 struct ecommunity
*ecom
;
1749 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
1753 return ecommunity_intern (ecom
);
1756 /* Set community rule structure. */
1757 struct route_map_rule_cmd route_set_ecommunity_soo_cmd
=
1760 route_set_ecommunity
,
1761 route_set_ecommunity_soo_compile
,
1762 route_set_ecommunity_free
,
1765 /* `set origin ORIGIN' */
1767 /* For origin set. */
1768 static route_map_result_t
1769 route_set_origin (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1772 struct bgp_info
*bgp_info
;
1774 if (type
== RMAP_BGP
)
1779 bgp_info
->attr
->origin
= *origin
;
1785 /* Compile function for origin set. */
1787 route_set_origin_compile (const char *arg
)
1791 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
1793 if (strcmp (arg
, "igp") == 0)
1795 else if (strcmp (arg
, "egp") == 0)
1803 /* Compile function for origin set. */
1805 route_set_origin_free (void *rule
)
1807 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1810 /* Set origin rule structure. */
1811 struct route_map_rule_cmd route_set_origin_cmd
=
1815 route_set_origin_compile
,
1816 route_set_origin_free
,
1819 /* `set atomic-aggregate' */
1821 /* For atomic aggregate set. */
1822 static route_map_result_t
1823 route_set_atomic_aggregate (void *rule
, struct prefix
*prefix
,
1824 route_map_object_t type
, void *object
)
1826 struct bgp_info
*bgp_info
;
1828 if (type
== RMAP_BGP
)
1831 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
1837 /* Compile function for atomic aggregate. */
1839 route_set_atomic_aggregate_compile (const char *arg
)
1844 /* Compile function for atomic aggregate. */
1846 route_set_atomic_aggregate_free (void *rule
)
1851 /* Set atomic aggregate rule structure. */
1852 struct route_map_rule_cmd route_set_atomic_aggregate_cmd
=
1855 route_set_atomic_aggregate
,
1856 route_set_atomic_aggregate_compile
,
1857 route_set_atomic_aggregate_free
,
1860 /* `set aggregator as AS A.B.C.D' */
1864 struct in_addr address
;
1867 static route_map_result_t
1868 route_set_aggregator_as (void *rule
, struct prefix
*prefix
,
1869 route_map_object_t type
, void *object
)
1871 struct bgp_info
*bgp_info
;
1872 struct aggregator
*aggregator
;
1873 struct attr_extra
*ae
;
1875 if (type
== RMAP_BGP
)
1879 ae
= bgp_attr_extra_get (bgp_info
->attr
);
1881 ae
->aggregator_as
= aggregator
->as
;
1882 ae
->aggregator_addr
= aggregator
->address
;
1883 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
);
1890 route_set_aggregator_as_compile (const char *arg
)
1892 struct aggregator
*aggregator
;
1896 aggregator
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct aggregator
));
1897 sscanf (arg
, "%s %s", as
, address
);
1899 aggregator
->as
= strtoul (as
, NULL
, 10);
1900 inet_aton (address
, &aggregator
->address
);
1906 route_set_aggregator_as_free (void *rule
)
1908 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1911 struct route_map_rule_cmd route_set_aggregator_as_cmd
=
1914 route_set_aggregator_as
,
1915 route_set_aggregator_as_compile
,
1916 route_set_aggregator_as_free
,
1919 /* Set tag to object. object must be pointer to struct bgp_info */
1920 static route_map_result_t
1921 route_set_tag (void *rule
, struct prefix
*prefix
,
1922 route_map_object_t type
, void *object
)
1925 struct bgp_info
*bgp_info
;
1926 struct attr_extra
*ae
;
1928 if (type
== RMAP_BGP
)
1932 ae
= bgp_attr_extra_get (bgp_info
->attr
);
1942 /* Route map `tag' compile function. Given string is converted to u_short. */
1944 route_set_tag_compile (const char *arg
)
1949 /* tag value shoud be integer. */
1950 if (! all_digit (arg
))
1958 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
1968 /* Free route map's tag value. */
1970 route_set_tag_free (void *rule
)
1972 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1976 /* Route map commands for tag set. */
1977 struct route_map_rule_cmd route_set_tag_cmd
=
1981 route_set_tag_compile
,
1987 /* `match ipv6 address IP_ACCESS_LIST' */
1989 static route_map_result_t
1990 route_match_ipv6_address (void *rule
, struct prefix
*prefix
,
1991 route_map_object_t type
, void *object
)
1993 struct access_list
*alist
;
1995 if (type
== RMAP_BGP
)
1997 alist
= access_list_lookup (AFI_IP6
, (char *) rule
);
1999 return RMAP_NOMATCH
;
2001 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
2002 RMAP_NOMATCH
: RMAP_MATCH
);
2004 return RMAP_NOMATCH
;
2008 route_match_ipv6_address_compile (const char *arg
)
2010 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2014 route_match_ipv6_address_free (void *rule
)
2016 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2019 /* Route map commands for ip address matching. */
2020 struct route_map_rule_cmd route_match_ipv6_address_cmd
=
2023 route_match_ipv6_address
,
2024 route_match_ipv6_address_compile
,
2025 route_match_ipv6_address_free
2028 /* `match ipv6 next-hop IP_ADDRESS' */
2030 static route_map_result_t
2031 route_match_ipv6_next_hop (void *rule
, struct prefix
*prefix
,
2032 route_map_object_t type
, void *object
)
2034 struct in6_addr
*addr
= rule
;
2035 struct bgp_info
*bgp_info
;
2037 if (type
== RMAP_BGP
)
2041 if (!bgp_info
->attr
->extra
)
2042 return RMAP_NOMATCH
;
2044 if (IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_global
, addr
))
2047 if (bgp_info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
&&
2048 IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_local
, rule
))
2051 return RMAP_NOMATCH
;
2054 return RMAP_NOMATCH
;
2058 route_match_ipv6_next_hop_compile (const char *arg
)
2060 struct in6_addr
*address
;
2063 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2065 ret
= inet_pton (AF_INET6
, arg
, address
);
2068 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2076 route_match_ipv6_next_hop_free (void *rule
)
2078 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2081 struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
=
2084 route_match_ipv6_next_hop
,
2085 route_match_ipv6_next_hop_compile
,
2086 route_match_ipv6_next_hop_free
2089 /* `match ipv6 address prefix-list PREFIX_LIST' */
2091 static route_map_result_t
2092 route_match_ipv6_address_prefix_list (void *rule
, struct prefix
*prefix
,
2093 route_map_object_t type
, void *object
)
2095 struct prefix_list
*plist
;
2097 if (type
== RMAP_BGP
)
2099 plist
= prefix_list_lookup (AFI_IP6
, (char *) rule
);
2101 return RMAP_NOMATCH
;
2103 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
2104 RMAP_NOMATCH
: RMAP_MATCH
);
2106 return RMAP_NOMATCH
;
2110 route_match_ipv6_address_prefix_list_compile (const char *arg
)
2112 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2116 route_match_ipv6_address_prefix_list_free (void *rule
)
2118 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2121 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
=
2123 "ipv6 address prefix-list",
2124 route_match_ipv6_address_prefix_list
,
2125 route_match_ipv6_address_prefix_list_compile
,
2126 route_match_ipv6_address_prefix_list_free
2129 /* `set ipv6 nexthop global IP_ADDRESS' */
2131 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2132 static route_map_result_t
2133 route_set_ipv6_nexthop_global (void *rule
, struct prefix
*prefix
,
2134 route_map_object_t type
, void *object
)
2136 struct in6_addr
*address
;
2137 struct bgp_info
*bgp_info
;
2139 if (type
== RMAP_BGP
)
2141 /* Fetch routemap's rule information. */
2145 /* Set next hop value. */
2146 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= *address
;
2148 /* Set nexthop length. */
2149 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2150 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
2152 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2153 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
2159 /* Route map `ip next-hop' compile function. Given string is converted
2160 to struct in_addr structure. */
2162 route_set_ipv6_nexthop_global_compile (const char *arg
)
2165 struct in6_addr
*address
;
2167 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2169 ret
= inet_pton (AF_INET6
, arg
, address
);
2173 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2180 /* Free route map's compiled `ip next-hop' value. */
2182 route_set_ipv6_nexthop_global_free (void *rule
)
2184 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2187 /* Route map commands for ip nexthop set. */
2188 struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd
=
2190 "ipv6 next-hop global",
2191 route_set_ipv6_nexthop_global
,
2192 route_set_ipv6_nexthop_global_compile
,
2193 route_set_ipv6_nexthop_global_free
2196 /* Set next-hop preference value. */
2197 static route_map_result_t
2198 route_set_ipv6_nexthop_prefer_global (void *rule
, struct prefix
*prefix
,
2199 route_map_object_t type
, void *object
)
2201 struct bgp_info
*bgp_info
;
2204 if (type
== RMAP_BGP
)
2206 /* Fetch routemap's rule information. */
2208 peer
= bgp_info
->peer
;
2210 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2211 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2213 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2215 /* Set next hop preference to global */
2216 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= TRUE
;
2217 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2218 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2222 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= FALSE
;
2223 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2224 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2231 route_set_ipv6_nexthop_prefer_global_compile (const char *arg
)
2235 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2241 /* Free route map's compiled `ip next-hop' value. */
2243 route_set_ipv6_nexthop_prefer_global_free (void *rule
)
2245 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2248 /* Route map commands for ip nexthop set preferred. */
2249 struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd
=
2251 "ipv6 next-hop prefer-global",
2252 route_set_ipv6_nexthop_prefer_global
,
2253 route_set_ipv6_nexthop_prefer_global_compile
,
2254 route_set_ipv6_nexthop_prefer_global_free
2257 /* `set ipv6 nexthop local IP_ADDRESS' */
2259 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2260 static route_map_result_t
2261 route_set_ipv6_nexthop_local (void *rule
, struct prefix
*prefix
,
2262 route_map_object_t type
, void *object
)
2264 struct in6_addr
*address
;
2265 struct bgp_info
*bgp_info
;
2267 if (type
== RMAP_BGP
)
2269 /* Fetch routemap's rule information. */
2273 /* Set next hop value. */
2274 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= *address
;
2276 /* Set nexthop length. */
2277 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
2278 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
2280 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2281 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
2287 /* Route map `ip nexthop' compile function. Given string is converted
2288 to struct in_addr structure. */
2290 route_set_ipv6_nexthop_local_compile (const char *arg
)
2293 struct in6_addr
*address
;
2295 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2297 ret
= inet_pton (AF_INET6
, arg
, address
);
2301 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2308 /* Free route map's compiled `ip nexthop' value. */
2310 route_set_ipv6_nexthop_local_free (void *rule
)
2312 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2315 /* Route map commands for ip nexthop set. */
2316 struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
2318 "ipv6 next-hop local",
2319 route_set_ipv6_nexthop_local
,
2320 route_set_ipv6_nexthop_local_compile
,
2321 route_set_ipv6_nexthop_local_free
2324 /* `set ipv6 nexthop peer-address' */
2326 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2327 static route_map_result_t
2328 route_set_ipv6_nexthop_peer (void *rule
, struct prefix
*prefix
,
2329 route_map_object_t type
, void *object
)
2331 struct in6_addr peer_address
;
2332 struct bgp_info
*bgp_info
;
2334 char peer_addr_buf
[INET6_ADDRSTRLEN
];
2336 if (type
== RMAP_BGP
)
2338 /* Fetch routemap's rule information. */
2340 peer
= bgp_info
->peer
;
2342 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2343 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2345 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2347 inet_pton (AF_INET6
, sockunion2str (peer
->su_remote
,
2351 /* Set next hop value and length in attribute. */
2352 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
))
2354 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= peer_address
;
2355 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= 32)
2356 bgp_info
->attr
->extra
->mp_nexthop_len
= 32;
2360 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= peer_address
;
2361 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2362 bgp_info
->attr
->extra
->mp_nexthop_len
= 16;
2366 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
2368 /* The next hop value will be set as part of packet rewrite.
2369 * Set the flags here to indicate that rewrite needs to be done.
2370 * Also, clear the value - we clear both global and link-local
2371 * nexthops, whether we send one or both is determined elsewhere.
2373 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2374 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
2375 /* clear next hop value. */
2376 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
),
2377 0, sizeof (struct in6_addr
));
2378 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
),
2379 0, sizeof (struct in6_addr
));
2386 /* Route map `ip next-hop' compile function. Given string is converted
2387 to struct in_addr structure. */
2389 route_set_ipv6_nexthop_peer_compile (const char *arg
)
2393 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2399 /* Free route map's compiled `ip next-hop' value. */
2401 route_set_ipv6_nexthop_peer_free (void *rule
)
2403 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2406 /* Route map commands for ip nexthop set. */
2407 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
=
2409 "ipv6 next-hop peer-address",
2410 route_set_ipv6_nexthop_peer
,
2411 route_set_ipv6_nexthop_peer_compile
,
2412 route_set_ipv6_nexthop_peer_free
2415 #endif /* HAVE_IPV6 */
2417 /* `set vpnv4 nexthop A.B.C.D' */
2419 static route_map_result_t
2420 route_set_vpnv4_nexthop (void *rule
, struct prefix
*prefix
,
2421 route_map_object_t type
, void *object
)
2423 struct in_addr
*address
;
2424 struct bgp_info
*bgp_info
;
2426 if (type
== RMAP_BGP
)
2428 /* Fetch routemap's rule information. */
2432 /* Set next hop value. */
2433 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global_in
= *address
;
2434 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_len
= 4;
2441 route_set_vpnv4_nexthop_compile (const char *arg
)
2444 struct in_addr
*address
;
2446 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2448 ret
= inet_aton (arg
, address
);
2452 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2460 route_set_vpnv4_nexthop_free (void *rule
)
2462 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2465 /* Route map commands for ip nexthop set. */
2466 struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
=
2469 route_set_vpnv4_nexthop
,
2470 route_set_vpnv4_nexthop_compile
,
2471 route_set_vpnv4_nexthop_free
2474 /* `set originator-id' */
2476 /* For origin set. */
2477 static route_map_result_t
2478 route_set_originator_id (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
2480 struct in_addr
*address
;
2481 struct bgp_info
*bgp_info
;
2483 if (type
== RMAP_BGP
)
2488 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
);
2489 (bgp_attr_extra_get (bgp_info
->attr
))->originator_id
= *address
;
2495 /* Compile function for originator-id set. */
2497 route_set_originator_id_compile (const char *arg
)
2500 struct in_addr
*address
;
2502 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2504 ret
= inet_aton (arg
, address
);
2508 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2515 /* Compile function for originator_id set. */
2517 route_set_originator_id_free (void *rule
)
2519 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2522 /* Set originator-id rule structure. */
2523 struct route_map_rule_cmd route_set_originator_id_cmd
=
2526 route_set_originator_id
,
2527 route_set_originator_id_compile
,
2528 route_set_originator_id_free
,
2531 /* Add bgp route map rule. */
2533 bgp_route_match_add (struct vty
*vty
, struct route_map_index
*index
,
2534 const char *command
, const char *arg
,
2535 route_map_event_t type
)
2539 ret
= route_map_add_match (index
, command
, arg
);
2544 case RMAP_RULE_MISSING
:
2545 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2547 case RMAP_COMPILE_ERROR
:
2548 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2553 if (type
!= RMAP_EVENT_MATCH_ADDED
)
2555 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
2561 /* Delete bgp route map rule. */
2563 bgp_route_match_delete (struct vty
*vty
, struct route_map_index
*index
,
2564 const char *command
, const char *arg
,
2565 route_map_event_t type
)
2568 char *dep_name
= NULL
;
2570 char *rmap_name
= NULL
;
2572 if (type
!= RMAP_EVENT_MATCH_DELETED
)
2574 /* ignore the mundane, the types without any dependency */
2577 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
2578 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
2582 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
2584 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
2587 ret
= route_map_delete_match (index
, command
, dep_name
);
2592 case RMAP_RULE_MISSING
:
2593 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2595 case RMAP_COMPILE_ERROR
:
2596 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2600 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2602 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2606 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
2607 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
2610 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2612 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2617 /* Add bgp route map rule. */
2619 bgp_route_set_add (struct vty
*vty
, struct route_map_index
*index
,
2620 const char *command
, const char *arg
)
2624 ret
= route_map_add_set (index
, command
, arg
);
2629 case RMAP_RULE_MISSING
:
2630 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2632 case RMAP_COMPILE_ERROR
:
2633 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2640 /* Delete bgp route map rule. */
2642 bgp_route_set_delete (struct vty
*vty
, struct route_map_index
*index
,
2643 const char *command
, const char *arg
)
2647 ret
= route_map_delete_set (index
, command
, arg
);
2652 case RMAP_RULE_MISSING
:
2653 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2655 case RMAP_COMPILE_ERROR
:
2656 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2664 * This is the workhorse routine for processing in/out routemap
2668 bgp_route_map_process_peer (const char *rmap_name
, struct route_map
*map
,
2669 struct peer
*peer
, int afi
, int safi
,
2674 struct bgp_filter
*filter
;
2676 if (!peer
|| !rmap_name
)
2679 filter
= &peer
->filter
[afi
][safi
];
2681 * in is for non-route-server clients,
2682 * out is for all peers
2684 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2686 if (filter
->map
[RMAP_IN
].name
&&
2687 (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0))
2689 filter
->map
[RMAP_IN
].map
= map
;
2691 if (route_update
&& peer
->status
== Established
)
2693 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2694 PEER_FLAG_SOFT_RECONFIG
))
2696 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2697 zlog_debug("Processing route_map %s update on "
2698 "peer %s (inbound, soft-reconfig)",
2699 rmap_name
, peer
->host
);
2701 bgp_soft_reconfig_in (peer
, afi
, safi
);
2703 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2704 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2707 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2708 zlog_debug("Processing route_map %s update on "
2709 "peer %s (inbound, route-refresh)",
2710 rmap_name
, peer
->host
);
2711 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2717 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2721 if (update
&& route_update
&& peer
->status
== Established
)
2723 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2724 PEER_FLAG_SOFT_RECONFIG
))
2726 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2727 zlog_debug("Processing route_map %s update on "
2728 "peer %s (import, soft-reconfig)",
2729 rmap_name
, peer
->host
);
2731 bgp_soft_reconfig_in (peer
, afi
, safi
);
2733 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2734 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2736 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2737 zlog_debug("Processing route_map %s update on "
2738 "peer %s (import, route-refresh)",
2739 rmap_name
, peer
->host
);
2740 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2742 /* DD: Else, what else do we do ? Reset peer ? */
2747 * For outbound, unsuppress and default-originate map change (content or
2748 * map created), merely update the "config" here, the actual route
2749 * announcement happens at the group level.
2751 if (filter
->map
[RMAP_OUT
].name
&&
2752 (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
2753 filter
->map
[RMAP_OUT
].map
= map
;
2755 if (filter
->usmap
.name
&&
2756 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
2757 filter
->usmap
.map
= map
;
2759 if (peer
->default_rmap
[afi
][safi
].name
&&
2760 (strcmp (rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
2761 peer
->default_rmap
[afi
][safi
].map
= map
;
2765 bgp_route_map_update_peer_group(const char *rmap_name
, struct route_map
*map
,
2768 struct peer_group
*group
;
2769 struct listnode
*node
, *nnode
;
2770 struct bgp_filter
*filter
;
2777 /* All the peers have been updated correctly already. This is
2778 * just updating the placeholder data. No real update required.
2780 for (ALL_LIST_ELEMENTS (bgp
->group
, node
, nnode
, group
))
2781 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2782 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2784 filter
= &group
->conf
->filter
[afi
][safi
];
2786 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++)
2788 if ((filter
->map
[direct
].name
) &&
2789 (strcmp(rmap_name
, filter
->map
[direct
].name
) == 0))
2790 filter
->map
[direct
].map
= map
;
2793 if (filter
->usmap
.name
&&
2794 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
2795 filter
->usmap
.map
= map
;
2800 * Note that if an extreme number (tens of thousands) of route-maps are in use
2801 * and if bgp has an extreme number of peers, network statements, etc then this
2802 * function can consume a lot of cycles. This is due to this function being
2803 * called for each route-map and within this function we walk the list of peers,
2804 * network statements, etc looking to see if they use this route-map.
2807 bgp_route_map_process_update (struct bgp
*bgp
, const char *rmap_name
, int route_update
)
2813 struct bgp_node
*bn
;
2814 struct bgp_static
*bgp_static
;
2815 struct listnode
*node
, *nnode
;
2816 struct route_map
*map
;
2817 char buf
[INET6_ADDRSTRLEN
];
2819 map
= route_map_lookup_by_name (rmap_name
);
2821 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
2824 /* Ignore dummy peer-group structure */
2825 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2828 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2829 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2831 /* Ignore inactive AFI/SAFI */
2832 if (! peer
->afc
[afi
][safi
])
2835 /* process in/out/import/export/default-orig route-maps */
2836 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
, safi
, route_update
);
2840 /* for outbound/default-orig route-maps, process for groups */
2841 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
2844 /* update peer-group config (template) */
2845 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
2847 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2848 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2850 /* For table route-map updates. */
2851 if (bgp
->table_map
[afi
][safi
].name
&&
2852 (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
) == 0))
2854 bgp
->table_map
[afi
][safi
].map
= map
;
2856 if (BGP_DEBUG (zebra
, ZEBRA
))
2857 zlog_debug("Processing route_map %s update on "
2858 "table map", rmap_name
);
2860 bgp_zebra_announce_table(bgp
, afi
, safi
);
2863 /* For network route-map updates. */
2864 for (bn
= bgp_table_top (bgp
->route
[afi
][safi
]); bn
; bn
= bgp_route_next (bn
))
2865 if ((bgp_static
= bn
->info
) != NULL
)
2867 if (bgp_static
->rmap
.name
&&
2868 (strcmp(rmap_name
, bgp_static
->rmap
.name
) == 0))
2870 bgp_static
->rmap
.map
= map
;
2873 if (!bgp_static
->backdoor
)
2875 if (bgp_debug_zebra(&bn
->p
))
2876 zlog_debug("Processing route_map %s update on "
2877 "static route %s", rmap_name
,
2878 inet_ntop (bn
->p
.family
, &bn
->p
.u
.prefix
,
2879 buf
, INET6_ADDRSTRLEN
));
2880 bgp_static_update (bgp
, &bn
->p
, bgp_static
, afi
, safi
);
2886 /* For redistribute route-map updates. */
2887 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2888 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
2890 struct list
*red_list
;
2891 struct listnode
*node
;
2892 struct bgp_redist
*red
;
2894 red_list
= bgp
->redist
[afi
][i
];
2898 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
2900 if (red
->rmap
.name
&&
2901 (strcmp(rmap_name
, red
->rmap
.name
) == 0))
2903 red
->rmap
.map
= map
;
2907 if (BGP_DEBUG (zebra
, ZEBRA
))
2908 zlog_debug("Processing route_map %s update on "
2909 "redistributed routes", rmap_name
);
2911 bgp_redistribute_resend (bgp
, afi
, i
, red
->instance
);
2919 bgp_route_map_process_update_cb (char *rmap_name
)
2921 struct listnode
*node
, *nnode
;
2924 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2925 bgp_route_map_process_update(bgp
, rmap_name
, 1);
2931 bgp_route_map_update_timer(struct thread
*thread
)
2933 bm
->t_rmap_update
= NULL
;
2935 route_map_walk_update_list(bgp_route_map_process_update_cb
);
2941 bgp_route_map_mark_update (const char *rmap_name
)
2943 if (bm
->t_rmap_update
== NULL
)
2945 struct listnode
*node
, *nnode
;
2948 /* rmap_update_timer of 0 means don't do route updates */
2949 if (bm
->rmap_update_timer
)
2952 thread_add_timer(bm
->master
, bgp_route_map_update_timer
, NULL
,
2953 bm
->rmap_update_timer
);
2955 /* Signal the groups that a route-map update event has started */
2956 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2957 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
, 1, 1);
2961 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2962 bgp_route_map_process_update(bgp
, rmap_name
, 0);
2968 bgp_route_map_add (const char *rmap_name
)
2970 if (route_map_mark_updated(rmap_name
, 0) == 0)
2971 bgp_route_map_mark_update(rmap_name
);
2973 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
2977 bgp_route_map_delete (const char *rmap_name
)
2979 if (route_map_mark_updated(rmap_name
, 1) == 0)
2980 bgp_route_map_mark_update(rmap_name
);
2982 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
2986 bgp_route_map_event (route_map_event_t event
, const char *rmap_name
)
2988 if (route_map_mark_updated(rmap_name
, 0) == 0)
2989 bgp_route_map_mark_update(rmap_name
);
2991 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
2997 "match peer <A.B.C.D|X:X::X:X>",
2999 "Match peer address\n"
3000 "IP address of peer\n"
3001 "IPv6 address of peer\n")
3004 return bgp_route_match_add (vty
, vty
->index
, "peer", argv
[idx_ip
]->arg
,
3005 RMAP_EVENT_MATCH_ADDED
);
3008 DEFUN (match_peer_local
,
3009 match_peer_local_cmd
,
3012 "Match peer address\n"
3013 "Static or Redistributed routes\n")
3015 return bgp_route_match_add (vty
, vty
->index
, "peer", "local",
3016 RMAP_EVENT_MATCH_DELETED
);
3020 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3021 * "no match peer local",
3024 * "Match peer address\n"
3025 * "Static or Redistributed routes\n"
3027 * "no match peer (A.B.C.D|X:X::X:X)",
3030 * "Match peer address\n"
3031 * "IP address of peer\n"
3032 * "IPv6 address of peer\n"
3035 DEFUN (no_match_peer
,
3040 "Match peer address\n")
3042 return bgp_route_match_delete (vty
, vty
->index
, "peer", argv
[3]->arg
,
3043 RMAP_EVENT_MATCH_DELETED
);
3048 DEFUN (match_ip_address
,
3049 match_ip_address_cmd
,
3050 "match ip address <(1-199)|(1300-2699)|WORD>",
3053 "Match address of route\n"
3054 "IP access-list number\n"
3055 "IP access-list number (expanded range)\n"
3056 "IP Access-list name\n")
3059 return bgp_route_match_add (vty
, vty
->index
, "ip address", argv
[idx_acl
]->arg
,
3060 RMAP_EVENT_FILTER_ADDED
);
3064 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3065 * "no match ip address (<1-199>|<1300-2699>|WORD)",
3069 * "Match address of route\n"
3070 * "IP access-list number\n"
3071 * "IP access-list number (expanded range)\n"
3072 * "IP Access-list name\n"
3075 DEFUN (no_match_ip_address
,
3076 no_match_ip_address_cmd
,
3077 "no match ip address",
3081 "Match address of route\n")
3083 return bgp_route_match_delete (vty
, vty
->index
, "ip address", argv
[4]->arg
,
3084 RMAP_EVENT_FILTER_DELETED
);
3088 DEFUN (match_ip_next_hop
,
3089 match_ip_next_hop_cmd
,
3090 "match ip next-hop <(1-199)|(1300-2699)|WORD>",
3093 "Match next-hop address of route\n"
3094 "IP access-list number\n"
3095 "IP access-list number (expanded range)\n"
3096 "IP Access-list name\n")
3099 return bgp_route_match_add (vty
, vty
->index
, "ip next-hop", argv
[idx_acl
]->arg
,
3100 RMAP_EVENT_FILTER_ADDED
);
3104 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3105 * "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
3109 * "Match next-hop address of route\n"
3110 * "IP access-list number\n"
3111 * "IP access-list number (expanded range)\n"
3112 * "IP Access-list name\n"
3115 DEFUN (no_match_ip_next_hop
,
3116 no_match_ip_next_hop_cmd
,
3117 "no match ip next-hop",
3121 "Match next-hop address of route\n")
3123 return bgp_route_match_delete (vty
, vty
->index
, "ip next-hop", argv
[4]->arg
,
3124 RMAP_EVENT_FILTER_DELETED
);
3128 /* match probability { */
3130 DEFUN (match_probability
,
3131 match_probability_cmd
,
3132 "match probability (0-100)",
3134 "Match portion of routes defined by percentage value\n"
3135 "Percentage of routes\n")
3138 return bgp_route_match_add (vty
, vty
->index
, "probability", argv
[idx_number
]->arg
,
3139 RMAP_EVENT_MATCH_ADDED
);
3143 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3144 * "no match probability <1-99>",
3147 * "Match portion of routes defined by percentage value\n"
3148 * "Percentage of routes\n"
3151 DEFUN (no_match_probability
,
3152 no_match_probability_cmd
,
3153 "no match probability",
3156 "Match portion of routes defined by percentage value\n")
3158 return bgp_route_match_delete (vty
, vty
->index
, "probability", argv
[2]->arg
,
3159 RMAP_EVENT_MATCH_DELETED
);
3165 DEFUN (match_ip_route_source
,
3166 match_ip_route_source_cmd
,
3167 "match ip route-source <(1-199)|(1300-2699)|WORD>",
3170 "Match advertising source address of route\n"
3171 "IP access-list number\n"
3172 "IP access-list number (expanded range)\n"
3173 "IP standard access-list name\n")
3176 return bgp_route_match_add (vty
, vty
->index
, "ip route-source", argv
[idx_acl
]->arg
,
3177 RMAP_EVENT_FILTER_ADDED
);
3181 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3182 * "no match ip route-source (<1-199>|<1300-2699>|WORD)",
3186 * "Match advertising source address of route\n"
3187 * "IP access-list number\n"
3188 * "IP access-list number (expanded range)\n"
3189 * "IP standard access-list name\n"
3192 DEFUN (no_match_ip_route_source
,
3193 no_match_ip_route_source_cmd
,
3194 "no match ip route-source",
3198 "Match advertising source address of route\n")
3200 return bgp_route_match_delete (vty
, vty
->index
, "ip route-source",
3201 argv
[4]->arg
, RMAP_EVENT_FILTER_DELETED
);
3205 DEFUN (match_ip_address_prefix_list
,
3206 match_ip_address_prefix_list_cmd
,
3207 "match ip address prefix-list WORD",
3210 "Match address of route\n"
3211 "Match entries of prefix-lists\n"
3212 "IP prefix-list name\n")
3215 return bgp_route_match_add (vty
, vty
->index
, "ip address prefix-list",
3216 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3220 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3221 * "no match ip address prefix-list WORD",
3225 * "Match address of route\n"
3226 * "Match entries of prefix-lists\n"
3227 * "IP prefix-list name\n"
3230 DEFUN (no_match_ip_address_prefix_list
,
3231 no_match_ip_address_prefix_list_cmd
,
3232 "no match ip address prefix-list",
3236 "Match address of route\n"
3237 "Match entries of prefix-lists\n")
3239 return bgp_route_match_delete (vty
, vty
->index
, "ip address prefix-list",
3240 argv
[5]->arg
, RMAP_EVENT_PLIST_DELETED
);
3244 DEFUN (match_ip_next_hop_prefix_list
,
3245 match_ip_next_hop_prefix_list_cmd
,
3246 "match ip next-hop prefix-list WORD",
3249 "Match next-hop address of route\n"
3250 "Match entries of prefix-lists\n"
3251 "IP prefix-list name\n")
3254 return bgp_route_match_add (vty
, vty
->index
, "ip next-hop prefix-list",
3255 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3259 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3260 * "no match ip next-hop prefix-list WORD",
3264 * "Match next-hop address of route\n"
3265 * "Match entries of prefix-lists\n"
3266 * "IP prefix-list name\n"
3269 DEFUN (no_match_ip_next_hop_prefix_list
,
3270 no_match_ip_next_hop_prefix_list_cmd
,
3271 "no match ip next-hop prefix-list",
3275 "Match next-hop address of route\n"
3276 "Match entries of prefix-lists\n")
3278 return bgp_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list",
3279 argv
[5]->arg
, RMAP_EVENT_PLIST_DELETED
);
3283 DEFUN (match_ip_route_source_prefix_list
,
3284 match_ip_route_source_prefix_list_cmd
,
3285 "match ip route-source prefix-list WORD",
3288 "Match advertising source address of route\n"
3289 "Match entries of prefix-lists\n"
3290 "IP prefix-list name\n")
3293 return bgp_route_match_add (vty
, vty
->index
, "ip route-source prefix-list",
3294 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3298 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3299 * "no match ip route-source prefix-list WORD",
3303 * "Match advertising source address of route\n"
3304 * "Match entries of prefix-lists\n"
3305 * "IP prefix-list name\n"
3308 DEFUN (no_match_ip_route_source_prefix_list
,
3309 no_match_ip_route_source_prefix_list_cmd
,
3310 "no match ip route-source prefix-list",
3314 "Match advertising source address of route\n"
3315 "Match entries of prefix-lists\n")
3317 return bgp_route_match_delete (vty
, vty
->index
, "ip route-source prefix-list",
3318 argv
[5]->arg
, RMAP_EVENT_PLIST_DELETED
);
3322 DEFUN (match_metric
,
3324 "match metric (0-4294967295)",
3326 "Match metric of route\n"
3330 return bgp_route_match_add (vty
, vty
->index
, "metric", argv
[idx_number
]->arg
,
3331 RMAP_EVENT_MATCH_ADDED
);
3335 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3336 * "no match metric <0-4294967295>",
3339 * "Match metric of route\n"
3343 DEFUN (no_match_metric
,
3344 no_match_metric_cmd
,
3348 "Match metric of route\n")
3350 return bgp_route_match_delete (vty
, vty
->index
, "metric",
3352 RMAP_EVENT_MATCH_DELETED
);
3356 DEFUN (match_local_pref
,
3357 match_local_pref_cmd
,
3358 "match local-preference (0-4294967295)",
3360 "Match local-preference of route\n"
3364 return bgp_route_match_add (vty
, vty
->index
, "local-preference", argv
[idx_number
]->arg
,
3365 RMAP_EVENT_MATCH_ADDED
);
3369 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3370 * "no match local-preference <0-4294967295>",
3373 * "Match local preference of route\n"
3374 * "Local preference value\n"
3377 DEFUN (no_match_local_pref
,
3378 no_match_local_pref_cmd
,
3379 "no match local-preference",
3382 "Match local preference of route\n")
3384 return bgp_route_match_delete (vty
, vty
->index
, "local-preference",
3386 RMAP_EVENT_MATCH_DELETED
);
3390 DEFUN (match_community
,
3391 match_community_cmd
,
3392 "match community <(1-99)|(100-500)|WORD>",
3394 "Match BGP community list\n"
3395 "Community-list number (standard)\n"
3396 "Community-list number (expanded)\n"
3397 "Community-list name\n")
3399 int idx_comm_list
= 2;
3400 return bgp_route_match_add (vty
, vty
->index
, "community", argv
[idx_comm_list
]->arg
,
3401 RMAP_EVENT_CLIST_ADDED
);
3404 DEFUN (match_community_exact
,
3405 match_community_exact_cmd
,
3406 "match community <(1-99)|(100-500)|WORD> exact-match",
3408 "Match BGP community list\n"
3409 "Community-list number (standard)\n"
3410 "Community-list number (expanded)\n"
3411 "Community-list name\n"
3412 "Do exact matching of communities\n")
3414 int idx_comm_list
= 2;
3418 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3419 strlen (argv
[idx_comm_list
]->arg
) + strlen ("exact-match") + 2);
3421 sprintf (argstr
, "%s exact-match", argv
[idx_comm_list
]->arg
);
3423 ret
= bgp_route_match_add (vty
, vty
->index
, "community", argstr
,
3424 RMAP_EVENT_CLIST_ADDED
);
3426 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3432 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3433 * "no match community (<1-99>|<100-500>|WORD)",
3436 * "Match BGP community list\n"
3437 * "Community-list number (standard)\n"
3438 * "Community-list number (expanded)\n"
3439 * "Community-list name\n"
3441 * "no match community (<1-99>|<100-500>|WORD) exact-match",
3444 * "Match BGP community list\n"
3445 * "Community-list number (standard)\n"
3446 * "Community-list number (expanded)\n"
3447 * "Community-list name\n"
3448 * "Do exact matching of communities\n"
3451 DEFUN (no_match_community
,
3452 no_match_community_cmd
,
3453 "no match community",
3456 "Match BGP community list\n")
3458 return bgp_route_match_delete (vty
, vty
->index
, "community", NULL
,
3459 RMAP_EVENT_CLIST_DELETED
);
3464 DEFUN (match_ecommunity
,
3465 match_ecommunity_cmd
,
3466 "match extcommunity <(1-99)|(100-500)|WORD>",
3468 "Match BGP/VPN extended community list\n"
3469 "Extended community-list number (standard)\n"
3470 "Extended community-list number (expanded)\n"
3471 "Extended community-list name\n")
3473 int idx_comm_list
= 2;
3474 return bgp_route_match_add (vty
, vty
->index
, "extcommunity", argv
[idx_comm_list
]->arg
,
3475 RMAP_EVENT_ECLIST_ADDED
);
3479 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3480 * "no match extcommunity (<1-99>|<100-500>|WORD)",
3483 * "Match BGP/VPN extended community list\n"
3484 * "Extended community-list number (standard)\n"
3485 * "Extended community-list number (expanded)\n"
3486 * "Extended community-list name\n"
3489 DEFUN (no_match_ecommunity
,
3490 no_match_ecommunity_cmd
,
3491 "no match extcommunity",
3494 "Match BGP/VPN extended community list\n")
3496 return bgp_route_match_delete (vty
, vty
->index
, "extcommunity", NULL
,
3497 RMAP_EVENT_ECLIST_DELETED
);
3501 DEFUN (match_aspath
,
3503 "match as-path WORD",
3505 "Match BGP AS path list\n"
3506 "AS path access-list name\n")
3509 return bgp_route_match_add (vty
, vty
->index
, "as-path", argv
[idx_word
]->arg
,
3510 RMAP_EVENT_ASLIST_ADDED
);
3514 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3515 * "no match as-path WORD",
3518 * "Match BGP AS path list\n"
3519 * "AS path access-list name\n"
3522 DEFUN (no_match_aspath
,
3523 no_match_aspath_cmd
,
3527 "Match BGP AS path list\n")
3529 return bgp_route_match_delete (vty
, vty
->index
, "as-path", NULL
,
3530 RMAP_EVENT_ASLIST_DELETED
);
3534 DEFUN (match_origin
,
3536 "match origin <egp|igp|incomplete>",
3541 "unknown heritage\n")
3544 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
3545 return bgp_route_match_add (vty
, vty
->index
, "origin", "igp",
3546 RMAP_EVENT_MATCH_ADDED
);
3547 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
3548 return bgp_route_match_add (vty
, vty
->index
, "origin", "egp",
3549 RMAP_EVENT_MATCH_ADDED
);
3550 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3551 return bgp_route_match_add (vty
, vty
->index
, "origin", "incomplete",
3552 RMAP_EVENT_MATCH_ADDED
);
3558 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3559 * "no match origin (egp|igp|incomplete)",
3562 * "BGP origin code\n"
3565 * "unknown heritage\n"
3568 DEFUN (no_match_origin
,
3569 no_match_origin_cmd
,
3573 "BGP origin code\n")
3575 return bgp_route_match_delete (vty
, vty
->index
, "origin", NULL
,
3576 RMAP_EVENT_MATCH_DELETED
);
3580 DEFUN (match_interface
,
3581 match_interface_cmd
,
3582 "match interface WORD",
3584 "Match first hop interface of route\n"
3588 return bgp_route_match_add (vty
, vty
->index
, "interface", argv
[idx_word
]->arg
,
3589 RMAP_EVENT_MATCH_ADDED
);
3593 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3594 * "no match interface WORD",
3597 * "Match first hop interface of route\n"
3598 * "Interface name\n"
3601 DEFUN (no_match_interface
,
3602 no_match_interface_cmd
,
3603 "no match interface",
3606 "Match first hop interface of route\n")
3608 return bgp_route_match_delete (vty
, vty
->index
, "interface", argv
[3]->arg
,
3609 RMAP_EVENT_MATCH_DELETED
);
3615 "match tag (1-65535)",
3617 "Match tag of route\n"
3621 return bgp_route_match_add (vty
, vty
->index
, "tag", argv
[idx_number
]->arg
,
3622 RMAP_EVENT_MATCH_ADDED
);
3626 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3627 * "no match tag <1-65535>",
3630 * "Match tag of route\n"
3634 DEFUN (no_match_tag
,
3639 "Match tag of route\n")
3641 return bgp_route_match_delete (vty
, vty
->index
, "tag", argv
[3]->arg
,
3642 RMAP_EVENT_MATCH_DELETED
);
3647 DEFUN (set_ip_nexthop
,
3649 "set ip next-hop A.B.C.D",
3652 "Next hop address\n"
3653 "IP address of next hop\n")
3659 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
3662 vty_out (vty
, "%% Malformed nexthop address%s", VTY_NEWLINE
);
3665 if (su
.sin
.sin_addr
.s_addr
== 0 ||
3666 IPV4_CLASS_DE(su
.sin
.sin_addr
.s_addr
))
3668 vty_out (vty
, "%% nexthop address cannot be 0.0.0.0, multicast "
3669 "or reserved%s", VTY_NEWLINE
);
3673 return bgp_route_set_add (vty
, vty
->index
, "ip next-hop", argv
[idx_ipv4
]->arg
);
3676 DEFUN (set_ip_nexthop_peer
,
3677 set_ip_nexthop_peer_cmd
,
3678 "set ip next-hop peer-address",
3681 "Next hop address\n"
3682 "Use peer address (for BGP only)\n")
3684 return bgp_route_set_add (vty
, vty
->index
, "ip next-hop", "peer-address");
3687 DEFUN (set_ip_nexthop_unchanged
,
3688 set_ip_nexthop_unchanged_cmd
,
3689 "set ip next-hop unchanged",
3692 "Next hop address\n"
3693 "Don't modify existing Next hop address\n")
3695 return bgp_route_set_add (vty
, vty
->index
, "ip next-hop", "unchanged");
3699 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3700 * "no set ip next-hop peer-address",
3704 * "Next hop address\n"
3705 * "Use peer address (for BGP only)\n"
3707 * "no set ip next-hop A.B.C.D",
3711 * "Next hop address\n"
3712 * "IP address of next hop\n"
3715 DEFUN (no_set_ip_nexthop
,
3716 no_set_ip_nexthop_cmd
,
3717 "no set ip next-hop",
3720 "Next hop address\n")
3722 return bgp_route_set_delete (vty
, vty
->index
, "ip next-hop", argv
[4]->arg
);
3728 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3729 * "set metric (rtt|+rtt|-rtt)",
3731 * "Metric value for destination routing protocol\n"
3732 * "Assign round trip time\n"
3733 * "Add round trip time\n"
3734 * "Subtract round trip time\n"
3736 * "set metric <+/-metric>",
3738 * "Metric value for destination routing protocol\n"
3739 * "Add or subtract metric\n"
3744 "set metric (0-4294967295)",
3746 "Metric value for destination routing protocol\n"
3750 return bgp_route_set_add (vty
, vty
->index
, "metric", argv
[idx_number
]->arg
);
3756 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3757 * "no set metric <0-4294967295>",
3760 * "Metric value for destination routing protocol\n"
3764 DEFUN (no_set_metric
,
3769 "Metric value for destination routing protocol\n")
3771 return bgp_route_set_delete (vty
, vty
->index
, "metric", argv
[3]->arg
);
3775 DEFUN (set_local_pref
,
3777 "set local-preference (0-4294967295)",
3779 "BGP local preference path attribute\n"
3780 "Preference value\n")
3783 return bgp_route_set_add (vty
, vty
->index
, "local-preference", argv
[idx_number
]->arg
);
3787 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3788 * "no set local-preference <0-4294967295>",
3791 * "BGP local preference path attribute\n"
3792 * "Preference value\n"
3795 DEFUN (no_set_local_pref
,
3796 no_set_local_pref_cmd
,
3797 "no set local-preference",
3800 "BGP local preference path attribute\n")
3802 return bgp_route_set_delete (vty
, vty
->index
, "local-preference", argv
[3]->arg
);
3808 "set weight (0-4294967295)",
3810 "BGP weight for routing table\n"
3814 return bgp_route_set_add (vty
, vty
->index
, "weight", argv
[idx_number
]->arg
);
3818 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3819 * "no set weight <0-4294967295>",
3822 * "BGP weight for routing table\n"
3826 DEFUN (no_set_weight
,
3831 "BGP weight for routing table\n")
3833 return bgp_route_set_delete (vty
, vty
->index
, "weight", argv
[3]->arg
);
3838 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3839 * "set as-path prepend (last-as) <1-10>",
3841 * "Transform BGP AS_PATH attribute\n"
3842 * "Prepend to the as-path\n"
3843 * "Use the peer's AS-number\n"
3844 * "Number of times to insert"
3847 DEFUN (set_aspath_prepend
,
3848 set_aspath_prepend_cmd
,
3849 "set as-path prepend . (1-4294967295)",
3851 "Transform BGP AS_PATH attribute\n"
3852 "Prepend to the as-path\n"
3858 str
= argv_concat (argv
, argc
, 0);
3859 ret
= bgp_route_set_add (vty
, vty
->index
, "as-path prepend", str
);
3860 XFREE (MTYPE_TMP
, str
);
3867 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3868 * "no set as-path prepend . (1-4294967295)",
3871 * "Transform BGP AS_PATH attribute\n"
3872 * "Prepend to the as-path\n"
3876 DEFUN (no_set_aspath_prepend
,
3877 no_set_aspath_prepend_cmd
,
3878 "no set as-path prepend",
3881 "Transform BGP AS_PATH attribute\n"
3882 "Prepend to the as-path\n")
3887 str
= argv_concat (argv
, argc
, 0);
3888 ret
= bgp_route_set_delete (vty
, vty
->index
, "as-path prepend", str
);
3889 XFREE (MTYPE_TMP
, str
);
3894 DEFUN (set_aspath_exclude
,
3895 set_aspath_exclude_cmd
,
3896 "set as-path exclude . (1-4294967295)",
3898 "Transform BGP AS-path attribute\n"
3899 "Exclude from the as-path\n"
3905 str
= argv_concat (argv
, argc
, 0);
3906 ret
= bgp_route_set_add (vty
, vty
->index
, "as-path exclude", str
);
3907 XFREE (MTYPE_TMP
, str
);
3912 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
3913 * "no set as-path exclude . (1-4294967295)",
3916 * "Transform BGP AS_PATH attribute\n"
3917 * "Exclude from the as-path\n"
3921 DEFUN (no_set_aspath_exclude
,
3922 no_set_aspath_exclude_cmd
,
3923 "no set as-path exclude",
3926 "Transform BGP AS_PATH attribute\n"
3927 "Exclude from the as-path\n")
3932 str
= argv_concat (argv
, argc
, 0);
3933 ret
= bgp_route_set_delete (vty
, vty
->index
, "as-path exclude", str
);
3934 XFREE (MTYPE_TMP
, str
);
3939 DEFUN (set_community
,
3941 "set community .AA:NN",
3943 "BGP community attribute\n"
3950 struct community
*com
= NULL
;
3955 b
= buffer_new (1024);
3957 for (i
= 0; i
< argc
; i
++)
3959 if (strncmp (argv
[i
]->arg
, "additive", strlen (argv
[i
]->arg
)) == 0)
3966 buffer_putc (b
, ' ');
3970 if (strncmp (argv
[i
]->arg
, "internet", strlen (argv
[i
]->arg
)) == 0)
3972 buffer_putstr (b
, "internet");
3975 if (strncmp (argv
[i
]->arg
, "local-AS", strlen (argv
[i
]->arg
)) == 0)
3977 buffer_putstr (b
, "local-AS");
3980 if (strncmp (argv
[i
]->arg
, "no-a", strlen ("no-a")) == 0
3981 && strncmp (argv
[i
]->arg
, "no-advertise", strlen (argv
[i
]->arg
)) == 0)
3983 buffer_putstr (b
, "no-advertise");
3986 if (strncmp (argv
[i
]->arg
, "no-e", strlen ("no-e"))== 0
3987 && strncmp (argv
[i
]->arg
, "no-export", strlen (argv
[i
]->arg
)) == 0)
3989 buffer_putstr (b
, "no-export");
3992 buffer_putstr (b
, argv
[i
]->arg
);
3994 buffer_putc (b
, '\0');
3996 /* Fetch result string then compile it to communities attribute. */
3997 str
= buffer_getstr (b
);
4002 com
= community_str2com (str
);
4003 XFREE (MTYPE_TMP
, str
);
4006 /* Can't compile user input into communities attribute. */
4009 vty_out (vty
, "%% Malformed communities attribute%s", VTY_NEWLINE
);
4013 /* Set communites attribute string. */
4014 str
= community_str (com
);
4018 argstr
= XCALLOC (MTYPE_TMP
, strlen (str
) + strlen (" additive") + 1);
4019 strcpy (argstr
, str
);
4020 strcpy (argstr
+ strlen (str
), " additive");
4021 ret
= bgp_route_set_add (vty
, vty
->index
, "community", argstr
);
4022 XFREE (MTYPE_TMP
, argstr
);
4025 ret
= bgp_route_set_add (vty
, vty
->index
, "community", str
);
4027 community_free (com
);
4032 DEFUN (set_community_none
,
4033 set_community_none_cmd
,
4034 "set community none",
4036 "BGP community attribute\n"
4037 "No community attribute\n")
4039 return bgp_route_set_add (vty
, vty
->index
, "community", "none");
4043 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4044 * "no set community none",
4047 * "BGP community attribute\n"
4048 * "No community attribute\n"
4050 * "no set community .AA:NN",
4053 * "BGP community attribute\n"
4057 DEFUN (no_set_community
,
4058 no_set_community_cmd
,
4062 "BGP community attribute\n")
4064 return bgp_route_set_delete (vty
, vty
->index
, "community", NULL
);
4069 DEFUN (set_community_delete
,
4070 set_community_delete_cmd
,
4071 "set comm-list <(1-99)|(100-500)|WORD> delete",
4073 "set BGP community list (for deletion)\n"
4074 "Community-list number (standard)\n"
4075 "Community-list number (expanded)\n"
4076 "Community-list name\n"
4077 "Delete matching communities\n")
4079 int idx_comm_list
= 2;
4082 str
= XCALLOC (MTYPE_TMP
, strlen (argv
[idx_comm_list
]->arg
) + strlen (" delete") + 1);
4083 strcpy (str
, argv
[idx_comm_list
]->arg
);
4084 strcpy (str
+ strlen (argv
[idx_comm_list
]->arg
), " delete");
4086 bgp_route_set_add (vty
, vty
->index
, "comm-list", str
);
4088 XFREE (MTYPE_TMP
, str
);
4093 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4094 * "no set comm-list (<1-99>|<100-500>|WORD) delete",
4097 * "set BGP community list (for deletion)\n"
4098 * "Community-list number (standard)\n"
4099 * "Community-list number (expanded)\n"
4100 * "Community-list name\n"
4101 * "Delete matching communities\n"
4104 DEFUN (no_set_community_delete
,
4105 no_set_community_delete_cmd
,
4109 "set BGP community list (for deletion)\n")
4111 return bgp_route_set_delete (vty
, vty
->index
, "comm-list", NULL
);
4115 DEFUN (set_ecommunity_rt
,
4116 set_ecommunity_rt_cmd
,
4117 "set extcommunity rt .ASN:nn_or_IP-address:nn",
4119 "BGP extended community attribute\n"
4120 "Route Target extended community\n"
4121 "VPN extended community\n")
4126 str
= argv_concat (argv
, argc
, 0);
4127 ret
= bgp_route_set_add (vty
, vty
->index
, "extcommunity rt", str
);
4128 XFREE (MTYPE_TMP
, str
);
4134 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4135 * "no set extcommunity rt .ASN:nn_or_IP-address:nn",
4138 * "BGP extended community attribute\n"
4139 * "Route Target extended community\n"
4140 * "VPN extended community\n"
4143 DEFUN (no_set_ecommunity_rt
,
4144 no_set_ecommunity_rt_cmd
,
4145 "no set extcommunity rt",
4148 "BGP extended community attribute\n"
4149 "Route Target extended community\n")
4151 return bgp_route_set_delete (vty
, vty
->index
, "extcommunity rt", NULL
);
4155 DEFUN (set_ecommunity_soo
,
4156 set_ecommunity_soo_cmd
,
4157 "set extcommunity soo .ASN:nn_or_IP-address:nn",
4159 "BGP extended community attribute\n"
4160 "Site-of-Origin extended community\n"
4161 "VPN extended community\n")
4166 str
= argv_concat (argv
, argc
, 0);
4167 ret
= bgp_route_set_add (vty
, vty
->index
, "extcommunity soo", str
);
4168 XFREE (MTYPE_TMP
, str
);
4173 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4174 * "no set extcommunity soo .ASN:nn_or_IP-address:nn",
4177 * "BGP extended community attribute\n"
4178 * "Site-of-Origin extended community\n"
4179 * "VPN extended community\n"
4182 DEFUN (no_set_ecommunity_soo
,
4183 no_set_ecommunity_soo_cmd
,
4184 "no set extcommunity soo",
4187 "BGP extended community attribute\n"
4188 "Site-of-Origin extended community\n")
4190 return bgp_route_set_delete (vty
, vty
->index
, "extcommunity soo", NULL
);
4196 "set origin <egp|igp|incomplete>",
4201 "unknown heritage\n")
4204 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
4205 return bgp_route_set_add (vty
, vty
->index
, "origin", "igp");
4206 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
4207 return bgp_route_set_add (vty
, vty
->index
, "origin", "egp");
4208 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
4209 return bgp_route_set_add (vty
, vty
->index
, "origin", "incomplete");
4215 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4216 * "no set origin (egp|igp|incomplete)",
4219 * "BGP origin code\n"
4222 * "unknown heritage\n"
4225 DEFUN (no_set_origin
,
4230 "BGP origin code\n")
4232 return bgp_route_set_delete (vty
, vty
->index
, "origin", NULL
);
4236 DEFUN (set_atomic_aggregate
,
4237 set_atomic_aggregate_cmd
,
4238 "set atomic-aggregate",
4240 "BGP atomic aggregate attribute\n" )
4242 return bgp_route_set_add (vty
, vty
->index
, "atomic-aggregate", NULL
);
4245 DEFUN (no_set_atomic_aggregate
,
4246 no_set_atomic_aggregate_cmd
,
4247 "no set atomic-aggregate",
4250 "BGP atomic aggregate attribute\n" )
4252 return bgp_route_set_delete (vty
, vty
->index
, "atomic-aggregate", NULL
);
4255 DEFUN (set_aggregator_as
,
4256 set_aggregator_as_cmd
,
4257 "set aggregator as (1-4294967295) A.B.C.D",
4259 "BGP aggregator attribute\n"
4260 "AS number of aggregator\n"
4262 "IP address of aggregator\n")
4267 struct in_addr address
;
4270 ret
= inet_aton (argv
[idx_ipv4
]->arg
, &address
);
4273 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
4277 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
4278 strlen (argv
[idx_number
]->arg
) + strlen (argv
[idx_ipv4
]->arg
) + 2);
4280 sprintf (argstr
, "%s %s", argv
[idx_number
]->arg
, argv
[idx_ipv4
]->arg
);
4282 ret
= bgp_route_set_add (vty
, vty
->index
, "aggregator as", argstr
);
4284 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4290 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4291 * "no set aggregator as (1-4294967295) A.B.C.D",
4294 * "BGP aggregator attribute\n"
4295 * "AS number of aggregator\n"
4297 * "IP address of aggregator\n"
4300 DEFUN (no_set_aggregator_as
,
4301 no_set_aggregator_as_cmd
,
4302 "no set aggregator as",
4305 "BGP aggregator attribute\n"
4306 "AS number of aggregator\n")
4309 struct in_addr address
;
4313 return bgp_route_set_delete (vty
, vty
->index
, "aggregator as", NULL
);
4315 ret
= inet_aton (argv
[5]->arg
, &address
);
4318 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
4322 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
4323 strlen (argv
[4]->arg
) + strlen (argv
[5]->arg
) + 2);
4325 sprintf (argstr
, "%s %s", argv
[4]->arg
, argv
[5]->arg
);
4327 ret
= bgp_route_set_delete (vty
, vty
->index
, "aggregator as", argstr
);
4329 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4337 "set tag (1-65535)",
4339 "Tag value for routing protocol\n"
4343 return bgp_route_set_add (vty
, vty
->index
, "tag", argv
[idx_number
]->arg
);
4347 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4348 * "no set tag <1-65535>",
4351 * "Tag value for routing protocol\n"
4360 "Tag value for routing protocol\n")
4362 return bgp_route_set_delete (vty
, vty
->index
, "tag", argv
[3]->arg
);
4368 DEFUN (match_ipv6_address
,
4369 match_ipv6_address_cmd
,
4370 "match ipv6 address WORD",
4373 "Match IPv6 address of route\n"
4374 "IPv6 access-list name\n")
4377 return bgp_route_match_add (vty
, vty
->index
, "ipv6 address", argv
[idx_word
]->arg
,
4378 RMAP_EVENT_FILTER_ADDED
);
4381 DEFUN (no_match_ipv6_address
,
4382 no_match_ipv6_address_cmd
,
4383 "no match ipv6 address WORD",
4387 "Match IPv6 address of route\n"
4388 "IPv6 access-list name\n")
4391 return bgp_route_match_delete (vty
, vty
->index
, "ipv6 address", argv
[idx_word
]->arg
,
4392 RMAP_EVENT_FILTER_DELETED
);
4395 DEFUN (match_ipv6_next_hop
,
4396 match_ipv6_next_hop_cmd
,
4397 "match ipv6 next-hop X:X::X:X",
4400 "Match IPv6 next-hop address of route\n"
4401 "IPv6 address of next hop\n")
4404 return bgp_route_match_add (vty
, vty
->index
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4405 RMAP_EVENT_MATCH_ADDED
);
4408 DEFUN (no_match_ipv6_next_hop
,
4409 no_match_ipv6_next_hop_cmd
,
4410 "no match ipv6 next-hop X:X::X:X",
4414 "Match IPv6 next-hop address of route\n"
4415 "IPv6 address of next hop\n")
4418 return bgp_route_match_delete (vty
, vty
->index
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4419 RMAP_EVENT_MATCH_DELETED
);
4422 DEFUN (match_ipv6_address_prefix_list
,
4423 match_ipv6_address_prefix_list_cmd
,
4424 "match ipv6 address prefix-list WORD",
4427 "Match address of route\n"
4428 "Match entries of prefix-lists\n"
4429 "IP prefix-list name\n")
4432 return bgp_route_match_add (vty
, vty
->index
, "ipv6 address prefix-list",
4433 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
4436 DEFUN (no_match_ipv6_address_prefix_list
,
4437 no_match_ipv6_address_prefix_list_cmd
,
4438 "no match ipv6 address prefix-list WORD",
4442 "Match address of route\n"
4443 "Match entries of prefix-lists\n"
4444 "IP prefix-list name\n")
4447 return bgp_route_match_delete (vty
, vty
->index
, "ipv6 address prefix-list",
4448 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_DELETED
);
4451 DEFUN (set_ipv6_nexthop_peer
,
4452 set_ipv6_nexthop_peer_cmd
,
4453 "set ipv6 next-hop peer-address",
4456 "Next hop address\n"
4457 "Use peer address (for BGP only)\n")
4459 return bgp_route_set_add (vty
, vty
->index
, "ipv6 next-hop peer-address", NULL
);
4462 DEFUN (no_set_ipv6_nexthop_peer
,
4463 no_set_ipv6_nexthop_peer_cmd
,
4464 "no set ipv6 next-hop peer-address",
4468 "IPv6 next-hop address\n"
4469 "Use peer address (for BGP only)\n")
4471 return bgp_route_set_delete (vty
, vty
->index
, "ipv6 next-hop peer-address", NULL
);
4474 DEFUN (set_ipv6_nexthop_prefer_global
,
4475 set_ipv6_nexthop_prefer_global_cmd
,
4476 "set ipv6 next-hop prefer-global",
4479 "IPv6 next-hop address\n"
4480 "Prefer global over link-local if both exist\n")
4482 return bgp_route_set_add (vty
, vty
->index
, "ipv6 next-hop prefer-global", NULL
);;
4485 DEFUN (no_set_ipv6_nexthop_prefer_global
,
4486 no_set_ipv6_nexthop_prefer_global_cmd
,
4487 "no set ipv6 next-hop prefer-global",
4491 "IPv6 next-hop address\n"
4492 "Prefer global over link-local if both exist\n")
4494 return bgp_route_set_delete (vty
, vty
->index
, "ipv6 next-hop prefer-global", NULL
);
4497 DEFUN (set_ipv6_nexthop_global
,
4498 set_ipv6_nexthop_global_cmd
,
4499 "set ipv6 next-hop global X:X::X:X",
4502 "IPv6 next-hop address\n"
4503 "IPv6 global address\n"
4504 "IPv6 address of next hop\n")
4507 struct in6_addr addr
;
4510 ret
= inet_pton (AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
4513 vty_out (vty
, "%% Malformed nexthop address%s", VTY_NEWLINE
);
4516 if (IN6_IS_ADDR_UNSPECIFIED(&addr
) ||
4517 IN6_IS_ADDR_LOOPBACK(&addr
) ||
4518 IN6_IS_ADDR_MULTICAST(&addr
) ||
4519 IN6_IS_ADDR_LINKLOCAL(&addr
))
4521 vty_out (vty
, "%% Invalid global nexthop address%s", VTY_NEWLINE
);
4525 return bgp_route_set_add (vty
, vty
->index
, "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4529 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4530 * "no set ipv6 next-hop global X:X::X:X",
4534 * "IPv6 next-hop address\n"
4535 * "IPv6 global address\n"
4536 * "IPv6 address of next hop\n"
4539 DEFUN (no_set_ipv6_nexthop_global
,
4540 no_set_ipv6_nexthop_global_cmd
,
4541 "no set ipv6 next-hop global",
4545 "IPv6 next-hop address\n"
4546 "IPv6 global address\n")
4548 return bgp_route_set_delete (vty
, vty
->index
, "ipv6 next-hop global", argv
[5]->arg
);
4552 DEFUN (set_ipv6_nexthop_local
,
4553 set_ipv6_nexthop_local_cmd
,
4554 "set ipv6 next-hop local X:X::X:X",
4557 "IPv6 next-hop address\n"
4558 "IPv6 local address\n"
4559 "IPv6 address of next hop\n")
4562 struct in6_addr addr
;
4565 ret
= inet_pton (AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
4568 vty_out (vty
, "%% Malformed nexthop address%s", VTY_NEWLINE
);
4571 if (!IN6_IS_ADDR_LINKLOCAL(&addr
))
4573 vty_out (vty
, "%% Invalid link-local nexthop address%s", VTY_NEWLINE
);
4577 return bgp_route_set_add (vty
, vty
->index
, "ipv6 next-hop local", argv
[idx_ipv6
]->arg
);
4581 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4582 * "no set ipv6 next-hop local X:X::X:X",
4586 * "IPv6 next-hop address\n"
4587 * "IPv6 local address\n"
4588 * "IPv6 address of next hop\n"
4591 DEFUN (no_set_ipv6_nexthop_local
,
4592 no_set_ipv6_nexthop_local_cmd
,
4593 "no set ipv6 next-hop local",
4597 "IPv6 next-hop address\n"
4598 "IPv6 local address\n")
4600 return bgp_route_set_delete (vty
, vty
->index
, "ipv6 next-hop local", argv
[5]->arg
);
4603 #endif /* HAVE_IPV6 */
4605 DEFUN (set_vpnv4_nexthop
,
4606 set_vpnv4_nexthop_cmd
,
4607 "set vpnv4 next-hop A.B.C.D",
4609 "VPNv4 information\n"
4610 "VPNv4 next-hop address\n"
4611 "IP address of next hop\n")
4614 return bgp_route_set_add (vty
, vty
->index
, "vpnv4 next-hop", argv
[idx_ipv4
]->arg
);
4618 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4619 * "no set vpnv4 next-hop A.B.C.D",
4622 * "VPNv4 information\n"
4623 * "VPNv4 next-hop address\n"
4624 * "IP address of next hop\n"
4627 DEFUN (no_set_vpnv4_nexthop
,
4628 no_set_vpnv4_nexthop_cmd
,
4629 "no set vpnv4 next-hop",
4632 "VPNv4 information\n"
4633 "VPNv4 next-hop address\n")
4635 return bgp_route_set_delete (vty
, vty
->index
, "vpnv4 next-hop", argv
[4]->arg
);
4639 DEFUN (set_originator_id
,
4640 set_originator_id_cmd
,
4641 "set originator-id A.B.C.D",
4643 "BGP originator ID attribute\n"
4644 "IP address of originator\n")
4647 return bgp_route_set_add (vty
, vty
->index
, "originator-id", argv
[idx_ipv4
]->arg
);
4651 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
4652 * "no set originator-id A.B.C.D",
4655 * "BGP originator ID attribute\n"
4656 * "IP address of originator\n"
4659 DEFUN (no_set_originator_id
,
4660 no_set_originator_id_cmd
,
4661 "no set originator-id",
4664 "BGP originator ID attribute\n")
4666 return bgp_route_set_delete (vty
, vty
->index
, "originator-id", argv
[3]->arg
);
4670 /* Initialization of route map. */
4672 bgp_route_map_init (void)
4675 route_map_init_vty ();
4676 route_map_add_hook (bgp_route_map_add
);
4677 route_map_delete_hook (bgp_route_map_delete
);
4678 route_map_event_hook (bgp_route_map_event
);
4680 route_map_install_match (&route_match_peer_cmd
);
4681 route_map_install_match (&route_match_local_pref_cmd
);
4682 route_map_install_match (&route_match_ip_address_cmd
);
4683 route_map_install_match (&route_match_ip_next_hop_cmd
);
4684 route_map_install_match (&route_match_ip_route_source_cmd
);
4685 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
4686 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
4687 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd
);
4688 route_map_install_match (&route_match_aspath_cmd
);
4689 route_map_install_match (&route_match_community_cmd
);
4690 route_map_install_match (&route_match_ecommunity_cmd
);
4691 route_map_install_match (&route_match_local_pref_cmd
);
4692 route_map_install_match (&route_match_metric_cmd
);
4693 route_map_install_match (&route_match_origin_cmd
);
4694 route_map_install_match (&route_match_probability_cmd
);
4695 route_map_install_match (&route_match_interface_cmd
);
4696 route_map_install_match (&route_match_tag_cmd
);
4698 route_map_install_set (&route_set_ip_nexthop_cmd
);
4699 route_map_install_set (&route_set_local_pref_cmd
);
4700 route_map_install_set (&route_set_weight_cmd
);
4701 route_map_install_set (&route_set_metric_cmd
);
4702 route_map_install_set (&route_set_aspath_prepend_cmd
);
4703 route_map_install_set (&route_set_aspath_exclude_cmd
);
4704 route_map_install_set (&route_set_origin_cmd
);
4705 route_map_install_set (&route_set_atomic_aggregate_cmd
);
4706 route_map_install_set (&route_set_aggregator_as_cmd
);
4707 route_map_install_set (&route_set_community_cmd
);
4708 route_map_install_set (&route_set_community_delete_cmd
);
4709 route_map_install_set (&route_set_vpnv4_nexthop_cmd
);
4710 route_map_install_set (&route_set_originator_id_cmd
);
4711 route_map_install_set (&route_set_ecommunity_rt_cmd
);
4712 route_map_install_set (&route_set_ecommunity_soo_cmd
);
4713 route_map_install_set (&route_set_tag_cmd
);
4715 install_element (RMAP_NODE
, &match_peer_cmd
);
4716 install_element (RMAP_NODE
, &match_peer_local_cmd
);
4717 install_element (RMAP_NODE
, &no_match_peer_cmd
);
4718 install_element (RMAP_NODE
, &match_ip_address_cmd
);
4719 install_element (RMAP_NODE
, &no_match_ip_address_cmd
);
4720 install_element (RMAP_NODE
, &match_ip_next_hop_cmd
);
4721 install_element (RMAP_NODE
, &no_match_ip_next_hop_cmd
);
4722 install_element (RMAP_NODE
, &match_ip_route_source_cmd
);
4723 install_element (RMAP_NODE
, &no_match_ip_route_source_cmd
);
4724 install_element (RMAP_NODE
, &match_ip_address_prefix_list_cmd
);
4725 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_cmd
);
4726 install_element (RMAP_NODE
, &match_ip_next_hop_prefix_list_cmd
);
4727 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_cmd
);
4728 install_element (RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
4729 install_element (RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
4731 install_element (RMAP_NODE
, &match_aspath_cmd
);
4732 install_element (RMAP_NODE
, &no_match_aspath_cmd
);
4733 install_element (RMAP_NODE
, &match_metric_cmd
);
4734 install_element (RMAP_NODE
, &no_match_metric_cmd
);
4735 install_element (RMAP_NODE
, &match_local_pref_cmd
);
4736 install_element (RMAP_NODE
, &no_match_local_pref_cmd
);
4737 install_element (RMAP_NODE
, &match_community_cmd
);
4738 install_element (RMAP_NODE
, &match_community_exact_cmd
);
4739 install_element (RMAP_NODE
, &no_match_community_cmd
);
4740 install_element (RMAP_NODE
, &match_ecommunity_cmd
);
4741 install_element (RMAP_NODE
, &no_match_ecommunity_cmd
);
4742 install_element (RMAP_NODE
, &match_origin_cmd
);
4743 install_element (RMAP_NODE
, &no_match_origin_cmd
);
4744 install_element (RMAP_NODE
, &match_probability_cmd
);
4745 install_element (RMAP_NODE
, &no_match_probability_cmd
);
4746 install_element (RMAP_NODE
, &match_interface_cmd
);
4747 install_element (RMAP_NODE
, &no_match_interface_cmd
);
4748 install_element (RMAP_NODE
, &match_tag_cmd
);
4749 install_element (RMAP_NODE
, &no_match_tag_cmd
);
4751 install_element (RMAP_NODE
, &set_ip_nexthop_cmd
);
4752 install_element (RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
4753 install_element (RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
4754 install_element (RMAP_NODE
, &no_set_ip_nexthop_cmd
);
4755 install_element (RMAP_NODE
, &set_local_pref_cmd
);
4756 install_element (RMAP_NODE
, &no_set_local_pref_cmd
);
4757 install_element (RMAP_NODE
, &set_weight_cmd
);
4758 install_element (RMAP_NODE
, &no_set_weight_cmd
);
4759 install_element (RMAP_NODE
, &set_metric_cmd
);
4760 install_element (RMAP_NODE
, &no_set_metric_cmd
);
4761 install_element (RMAP_NODE
, &set_aspath_prepend_cmd
);
4762 install_element (RMAP_NODE
, &set_aspath_exclude_cmd
);
4763 install_element (RMAP_NODE
, &no_set_aspath_prepend_cmd
);
4764 install_element (RMAP_NODE
, &no_set_aspath_exclude_cmd
);
4765 install_element (RMAP_NODE
, &set_origin_cmd
);
4766 install_element (RMAP_NODE
, &no_set_origin_cmd
);
4767 install_element (RMAP_NODE
, &set_atomic_aggregate_cmd
);
4768 install_element (RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
4769 install_element (RMAP_NODE
, &set_aggregator_as_cmd
);
4770 install_element (RMAP_NODE
, &no_set_aggregator_as_cmd
);
4771 install_element (RMAP_NODE
, &set_community_cmd
);
4772 install_element (RMAP_NODE
, &set_community_none_cmd
);
4773 install_element (RMAP_NODE
, &no_set_community_cmd
);
4774 install_element (RMAP_NODE
, &set_community_delete_cmd
);
4775 install_element (RMAP_NODE
, &no_set_community_delete_cmd
);
4776 install_element (RMAP_NODE
, &set_ecommunity_rt_cmd
);
4777 install_element (RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
4778 install_element (RMAP_NODE
, &set_ecommunity_soo_cmd
);
4779 install_element (RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
4780 install_element (RMAP_NODE
, &set_vpnv4_nexthop_cmd
);
4781 install_element (RMAP_NODE
, &no_set_vpnv4_nexthop_cmd
);
4782 install_element (RMAP_NODE
, &set_originator_id_cmd
);
4783 install_element (RMAP_NODE
, &no_set_originator_id_cmd
);
4784 install_element (RMAP_NODE
, &set_tag_cmd
);
4785 install_element (RMAP_NODE
, &no_set_tag_cmd
);
4788 route_map_install_match (&route_match_ipv6_address_cmd
);
4789 route_map_install_match (&route_match_ipv6_next_hop_cmd
);
4790 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd
);
4791 route_map_install_set (&route_set_ipv6_nexthop_global_cmd
);
4792 route_map_install_set (&route_set_ipv6_nexthop_prefer_global_cmd
);
4793 route_map_install_set (&route_set_ipv6_nexthop_local_cmd
);
4794 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd
);
4796 install_element (RMAP_NODE
, &match_ipv6_address_cmd
);
4797 install_element (RMAP_NODE
, &no_match_ipv6_address_cmd
);
4798 install_element (RMAP_NODE
, &match_ipv6_next_hop_cmd
);
4799 install_element (RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
4800 install_element (RMAP_NODE
, &match_ipv6_address_prefix_list_cmd
);
4801 install_element (RMAP_NODE
, &no_match_ipv6_address_prefix_list_cmd
);
4802 install_element (RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
4803 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
4804 install_element (RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
4805 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
4806 install_element (RMAP_NODE
, &set_ipv6_nexthop_local_cmd
);
4807 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_local_cmd
);
4808 install_element (RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
4809 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
4810 #endif /* HAVE_IPV6 */
4814 bgp_route_map_terminate (void)
4816 /* ToDo: Cleanup all the used memory */
4818 route_map_add_hook (NULL
);
4819 route_map_delete_hook (NULL
);
4820 route_map_event_hook (NULL
);