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>
35 #endif /* HAVE_LIBPCREPOSIX */
37 #include "sockunion.h"
41 #include "bgpd/bgpd.h"
42 #include "bgpd/bgp_table.h"
43 #include "bgpd/bgp_attr.h"
44 #include "bgpd/bgp_aspath.h"
45 #include "bgpd/bgp_packet.h"
46 #include "bgpd/bgp_route.h"
47 #include "bgpd/bgp_zebra.h"
48 #include "bgpd/bgp_regex.h"
49 #include "bgpd/bgp_community.h"
50 #include "bgpd/bgp_clist.h"
51 #include "bgpd/bgp_filter.h"
52 #include "bgpd/bgp_mplsvpn.h"
53 #include "bgpd/bgp_ecommunity.h"
54 #include "bgpd/bgp_lcommunity.h"
55 #include "bgpd/bgp_vty.h"
56 #include "bgpd/bgp_debug.h"
59 # include "bgpd/rfapi/bgp_rfapi_cfg.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)
87 large-community : Done
88 large-comm-list : Done
91 default : (This will not be implemented by bgpd)
92 interface : (This will not be implemented by bgpd)
93 ip default : (This will not be implemented by bgpd)
95 ip precedence : (This will not be implemented by bgpd)
96 ip tos : (This will not be implemented by bgpd)
97 level : (This will not be implemented by bgpd)
98 local-preference : Done
100 metric-type : Not yet
107 set ipv6 next-hop global: Done
108 set ipv6 next-hop prefer-global: Done
109 set ipv6 next-hop local : Done
110 set as-path exclude : Done
114 /* generic value manipulation to be shared in multiple rules */
116 #define RMAP_VALUE_SET 0
117 #define RMAP_VALUE_ADD 1
118 #define RMAP_VALUE_SUB 2
128 route_value_match (struct rmap_value
*rv
, u_int32_t value
)
130 if (rv
->variable
== 0 && value
== rv
->value
)
137 route_value_adjust (struct rmap_value
*rv
, u_int32_t current
, struct peer
*peer
)
141 switch (rv
->variable
)
154 if (current
> UINT32_MAX
-value
)
156 return current
+ value
;
158 if (current
<= value
)
160 return current
- value
;
167 route_value_compile (const char *arg
)
169 u_int8_t action
= RMAP_VALUE_SET
, var
= 0;
170 unsigned long larg
= 0;
172 struct rmap_value
*rv
;
176 action
= RMAP_VALUE_ADD
;
179 else if (arg
[0] == '-')
181 action
= RMAP_VALUE_SUB
;
188 larg
= strtoul (arg
, &endptr
, 10);
189 if (*arg
== 0 || *endptr
!= 0 || errno
|| larg
> UINT32_MAX
)
194 if (strcmp(arg
, "rtt") == 0)
200 rv
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_value
));
211 route_value_free (void *rule
)
213 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
216 /* generic as path object to be shared in multiple rules */
219 route_aspath_compile (const char *arg
)
221 struct aspath
*aspath
;
223 aspath
= aspath_str2aspath (arg
);
230 route_aspath_free (void *rule
)
232 struct aspath
*aspath
= rule
;
233 aspath_free (aspath
);
236 /* 'match peer (A.B.C.D|X:X::X:X)' */
238 /* Compares the peer specified in the 'match peer' clause with the peer
239 received in bgp_info->peer. If it is the same, or if the peer structure
240 received is a peer_group containing it, returns RMAP_MATCH. */
241 static route_map_result_t
242 route_match_peer (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
246 union sockunion su_def
= { .sin
= { .sin_family
= AF_INET
,
247 .sin_addr
.s_addr
= INADDR_ANY
} };
248 struct peer_group
*group
;
250 struct listnode
*node
, *nnode
;
252 if (type
== RMAP_BGP
)
255 peer
= ((struct bgp_info
*) object
)->peer
;
257 if ( ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
) &&
258 ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_EXPORT
) )
261 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
262 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
263 if (sockunion_same (su
, &su_def
))
266 if ( CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_NETWORK
) ||
267 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
) ||
268 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_DEFAULT
))
275 if (! CHECK_FLAG (peer
->sflags
, PEER_STATUS_GROUP
))
277 if (sockunion_same (su
, &peer
->su
))
285 for (ALL_LIST_ELEMENTS (group
->peer
, node
, nnode
, peer
))
287 if (sockunion_same (su
, &peer
->su
))
297 route_match_peer_compile (const char *arg
)
302 su
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union sockunion
));
304 ret
= str2sockunion (strcmp(arg
, "local") ? arg
: "0.0.0.0", su
);
306 XFREE (MTYPE_ROUTE_MAP_COMPILED
, su
);
313 /* Free route map's compiled `ip address' value. */
315 route_match_peer_free (void *rule
)
317 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
320 /* Route map commands for ip address matching. */
321 struct route_map_rule_cmd route_match_peer_cmd
=
325 route_match_peer_compile
,
326 route_match_peer_free
329 /* `match ip address IP_ACCESS_LIST' */
331 /* Match function should return 1 if match is success else return
333 static route_map_result_t
334 route_match_ip_address (void *rule
, struct prefix
*prefix
,
335 route_map_object_t type
, void *object
)
337 struct access_list
*alist
;
338 /* struct prefix_ipv4 match; */
340 if (type
== RMAP_BGP
)
342 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
346 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
347 RMAP_NOMATCH
: RMAP_MATCH
);
352 /* Route map `ip address' match statement. `arg' should be
355 route_match_ip_address_compile (const char *arg
)
357 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
360 /* Free route map's compiled `ip address' value. */
362 route_match_ip_address_free (void *rule
)
364 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
367 /* Route map commands for ip address matching. */
368 struct route_map_rule_cmd route_match_ip_address_cmd
=
371 route_match_ip_address
,
372 route_match_ip_address_compile
,
373 route_match_ip_address_free
376 /* `match ip next-hop IP_ADDRESS' */
378 /* Match function return 1 if match is success else return zero. */
379 static route_map_result_t
380 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
381 route_map_object_t type
, void *object
)
383 struct access_list
*alist
;
384 struct bgp_info
*bgp_info
;
385 struct prefix_ipv4 p
;
387 if (type
== RMAP_BGP
)
391 p
.prefix
= bgp_info
->attr
->nexthop
;
392 p
.prefixlen
= IPV4_MAX_BITLEN
;
394 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
398 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
399 RMAP_NOMATCH
: RMAP_MATCH
);
404 /* Route map `ip next-hop' match statement. `arg' is
407 route_match_ip_next_hop_compile (const char *arg
)
409 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
412 /* Free route map's compiled `ip address' value. */
414 route_match_ip_next_hop_free (void *rule
)
416 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
419 /* Route map commands for ip next-hop matching. */
420 struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
423 route_match_ip_next_hop
,
424 route_match_ip_next_hop_compile
,
425 route_match_ip_next_hop_free
428 /* `match ip route-source ACCESS-LIST' */
430 /* Match function return 1 if match is success else return zero. */
431 static route_map_result_t
432 route_match_ip_route_source (void *rule
, struct prefix
*prefix
,
433 route_map_object_t type
, void *object
)
435 struct access_list
*alist
;
436 struct bgp_info
*bgp_info
;
438 struct prefix_ipv4 p
;
440 if (type
== RMAP_BGP
)
443 peer
= bgp_info
->peer
;
445 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
449 p
.prefix
= peer
->su
.sin
.sin_addr
;
450 p
.prefixlen
= IPV4_MAX_BITLEN
;
452 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
456 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
457 RMAP_NOMATCH
: RMAP_MATCH
);
462 /* Route map `ip route-source' match statement. `arg' is
465 route_match_ip_route_source_compile (const char *arg
)
467 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
470 /* Free route map's compiled `ip address' value. */
472 route_match_ip_route_source_free (void *rule
)
474 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
477 /* Route map commands for ip route-source matching. */
478 struct route_map_rule_cmd route_match_ip_route_source_cmd
=
481 route_match_ip_route_source
,
482 route_match_ip_route_source_compile
,
483 route_match_ip_route_source_free
486 /* `match ip address prefix-list PREFIX_LIST' */
488 static route_map_result_t
489 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
490 route_map_object_t type
, void *object
)
492 struct prefix_list
*plist
;
494 if (type
== RMAP_BGP
)
496 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
500 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
501 RMAP_NOMATCH
: RMAP_MATCH
);
507 route_match_ip_address_prefix_list_compile (const char *arg
)
509 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
513 route_match_ip_address_prefix_list_free (void *rule
)
515 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
518 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
520 "ip address prefix-list",
521 route_match_ip_address_prefix_list
,
522 route_match_ip_address_prefix_list_compile
,
523 route_match_ip_address_prefix_list_free
526 /* `match ip next-hop prefix-list PREFIX_LIST' */
528 static route_map_result_t
529 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
530 route_map_object_t type
, void *object
)
532 struct prefix_list
*plist
;
533 struct bgp_info
*bgp_info
;
534 struct prefix_ipv4 p
;
536 if (type
== RMAP_BGP
)
540 p
.prefix
= bgp_info
->attr
->nexthop
;
541 p
.prefixlen
= IPV4_MAX_BITLEN
;
543 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
547 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
548 RMAP_NOMATCH
: RMAP_MATCH
);
554 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
556 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
560 route_match_ip_next_hop_prefix_list_free (void *rule
)
562 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
565 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
567 "ip next-hop prefix-list",
568 route_match_ip_next_hop_prefix_list
,
569 route_match_ip_next_hop_prefix_list_compile
,
570 route_match_ip_next_hop_prefix_list_free
573 /* `match ip route-source prefix-list PREFIX_LIST' */
575 static route_map_result_t
576 route_match_ip_route_source_prefix_list (void *rule
, struct prefix
*prefix
,
577 route_map_object_t type
, void *object
)
579 struct prefix_list
*plist
;
580 struct bgp_info
*bgp_info
;
582 struct prefix_ipv4 p
;
584 if (type
== RMAP_BGP
)
587 peer
= bgp_info
->peer
;
589 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
593 p
.prefix
= peer
->su
.sin
.sin_addr
;
594 p
.prefixlen
= IPV4_MAX_BITLEN
;
596 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
600 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
601 RMAP_NOMATCH
: RMAP_MATCH
);
607 route_match_ip_route_source_prefix_list_compile (const char *arg
)
609 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
613 route_match_ip_route_source_prefix_list_free (void *rule
)
615 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
618 struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd
=
620 "ip route-source prefix-list",
621 route_match_ip_route_source_prefix_list
,
622 route_match_ip_route_source_prefix_list_compile
,
623 route_match_ip_route_source_prefix_list_free
626 /* `match local-preference LOCAL-PREF' */
628 /* Match function return 1 if match is success else return zero. */
629 static route_map_result_t
630 route_match_local_pref (void *rule
, struct prefix
*prefix
,
631 route_map_object_t type
, void *object
)
633 u_int32_t
*local_pref
;
634 struct bgp_info
*bgp_info
;
636 if (type
== RMAP_BGP
)
641 if (bgp_info
->attr
->local_pref
== *local_pref
)
649 /* Route map `match local-preference' match statement.
650 `arg' is local-pref value */
652 route_match_local_pref_compile (const char *arg
)
654 u_int32_t
*local_pref
;
656 unsigned long tmpval
;
658 /* Locpref value shoud be integer. */
659 if (! all_digit (arg
))
663 tmpval
= strtoul (arg
, &endptr
, 10);
664 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
667 local_pref
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
672 *local_pref
= tmpval
;
676 /* Free route map's compiled `match local-preference' value. */
678 route_match_local_pref_free (void *rule
)
680 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
683 /* Route map commands for metric matching. */
684 struct route_map_rule_cmd route_match_local_pref_cmd
=
687 route_match_local_pref
,
688 route_match_local_pref_compile
,
689 route_match_local_pref_free
692 /* `match metric METRIC' */
694 /* Match function return 1 if match is success else return zero. */
695 static route_map_result_t
696 route_match_metric (void *rule
, struct prefix
*prefix
,
697 route_map_object_t type
, void *object
)
699 struct rmap_value
*rv
;
700 struct bgp_info
*bgp_info
;
702 if (type
== RMAP_BGP
)
706 return route_value_match(rv
, bgp_info
->attr
->med
);
711 /* Route map commands for metric matching. */
712 struct route_map_rule_cmd route_match_metric_cmd
=
720 /* `match as-path ASPATH' */
722 /* Match function for as-path match. I assume given object is */
723 static route_map_result_t
724 route_match_aspath (void *rule
, struct prefix
*prefix
,
725 route_map_object_t type
, void *object
)
728 struct as_list
*as_list
;
729 struct bgp_info
*bgp_info
;
731 if (type
== RMAP_BGP
)
733 as_list
= as_list_lookup ((char *) rule
);
740 return ((as_list_apply (as_list
, bgp_info
->attr
->aspath
) == AS_FILTER_DENY
) ? RMAP_NOMATCH
: RMAP_MATCH
);
745 /* Compile function for as-path match. */
747 route_match_aspath_compile (const char *arg
)
749 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
752 /* Compile function for as-path match. */
754 route_match_aspath_free (void *rule
)
756 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
759 /* Route map commands for aspath matching. */
760 struct route_map_rule_cmd route_match_aspath_cmd
=
764 route_match_aspath_compile
,
765 route_match_aspath_free
768 /* `match community COMMUNIY' */
769 struct rmap_community
775 /* Match function for community match. */
776 static route_map_result_t
777 route_match_community (void *rule
, struct prefix
*prefix
,
778 route_map_object_t type
, void *object
)
780 struct community_list
*list
;
781 struct bgp_info
*bgp_info
;
782 struct rmap_community
*rcom
;
784 if (type
== RMAP_BGP
)
789 list
= community_list_lookup (bgp_clist
, rcom
->name
, COMMUNITY_LIST_MASTER
);
795 if (community_list_exact_match (bgp_info
->attr
->community
, list
))
800 if (community_list_match (bgp_info
->attr
->community
, list
))
807 /* Compile function for community match. */
809 route_match_community_compile (const char *arg
)
811 struct rmap_community
*rcom
;
815 rcom
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_community
));
817 p
= strchr (arg
, ' ');
821 rcom
->name
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
822 memcpy (rcom
->name
, arg
, len
);
827 rcom
->name
= XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
833 /* Compile function for community match. */
835 route_match_community_free (void *rule
)
837 struct rmap_community
*rcom
= rule
;
839 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
840 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
);
843 /* Route map commands for community matching. */
844 struct route_map_rule_cmd route_match_community_cmd
=
847 route_match_community
,
848 route_match_community_compile
,
849 route_match_community_free
852 /* Match function for lcommunity match. */
853 static route_map_result_t
854 route_match_lcommunity (void *rule
, struct prefix
*prefix
,
855 route_map_object_t type
, void *object
)
857 struct community_list
*list
;
858 struct bgp_info
*bgp_info
;
859 struct rmap_community
*rcom
;
861 if (type
== RMAP_BGP
)
866 list
= community_list_lookup (bgp_clist
, rcom
->name
,
867 LARGE_COMMUNITY_LIST_MASTER
);
871 if (bgp_info
->attr
->extra
&&
872 lcommunity_list_match (bgp_info
->attr
->extra
->lcommunity
, list
))
879 /* Compile function for community match. */
881 route_match_lcommunity_compile (const char *arg
)
883 struct rmap_community
*rcom
;
887 rcom
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_community
));
889 p
= strchr (arg
, ' ');
893 rcom
->name
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
894 memcpy (rcom
->name
, arg
, len
);
898 rcom
->name
= XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
904 /* Compile function for community match. */
906 route_match_lcommunity_free (void *rule
)
908 struct rmap_community
*rcom
= rule
;
910 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
911 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
);
914 /* Route map commands for community matching. */
915 struct route_map_rule_cmd route_match_lcommunity_cmd
=
918 route_match_lcommunity
,
919 route_match_lcommunity_compile
,
920 route_match_lcommunity_free
924 /* Match function for extcommunity match. */
925 static route_map_result_t
926 route_match_ecommunity (void *rule
, struct prefix
*prefix
,
927 route_map_object_t type
, void *object
)
929 struct community_list
*list
;
930 struct bgp_info
*bgp_info
;
932 if (type
== RMAP_BGP
)
936 if (!bgp_info
->attr
->extra
)
939 list
= community_list_lookup (bgp_clist
, (char *) rule
,
940 EXTCOMMUNITY_LIST_MASTER
);
944 if (ecommunity_list_match (bgp_info
->attr
->extra
->ecommunity
, list
))
950 /* Compile function for extcommunity match. */
952 route_match_ecommunity_compile (const char *arg
)
954 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
957 /* Compile function for extcommunity match. */
959 route_match_ecommunity_free (void *rule
)
961 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
964 /* Route map commands for community matching. */
965 struct route_map_rule_cmd route_match_ecommunity_cmd
=
968 route_match_ecommunity
,
969 route_match_ecommunity_compile
,
970 route_match_ecommunity_free
973 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
974 and `address-family vpnv4'. */
977 static route_map_result_t
978 route_match_origin (void *rule
, struct prefix
*prefix
,
979 route_map_object_t type
, void *object
)
982 struct bgp_info
*bgp_info
;
984 if (type
== RMAP_BGP
)
989 if (bgp_info
->attr
->origin
== *origin
)
997 route_match_origin_compile (const char *arg
)
1001 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
1003 if (strcmp (arg
, "igp") == 0)
1005 else if (strcmp (arg
, "egp") == 0)
1013 /* Free route map's compiled `ip address' value. */
1015 route_match_origin_free (void *rule
)
1017 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1020 /* Route map commands for origin matching. */
1021 struct route_map_rule_cmd route_match_origin_cmd
=
1025 route_match_origin_compile
,
1026 route_match_origin_free
1029 /* match probability { */
1031 static route_map_result_t
1032 route_match_probability (void *rule
, struct prefix
*prefix
,
1033 route_map_object_t type
, void *object
)
1037 switch (*(long *) rule
)
1040 case RAND_MAX
: return RMAP_MATCH
;
1042 if (r
< *(long *) rule
)
1048 return RMAP_NOMATCH
;
1052 route_match_probability_compile (const char *arg
)
1058 lobule
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (long));
1062 case 0: *lobule
= 0; break;
1063 case 100: *lobule
= RAND_MAX
; break;
1064 default: *lobule
= RAND_MAX
/ 100 * perc
;
1071 route_match_probability_free (void *rule
)
1073 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1076 struct route_map_rule_cmd route_match_probability_cmd
=
1079 route_match_probability
,
1080 route_match_probability_compile
,
1081 route_match_probability_free
1084 /* `match interface IFNAME' */
1085 /* Match function should return 1 if match is success else return
1087 static route_map_result_t
1088 route_match_interface (void *rule
, struct prefix
*prefix
,
1089 route_map_object_t type
, void *object
)
1091 struct interface
*ifp
;
1092 struct bgp_info
*info
;
1094 if (type
== RMAP_BGP
)
1098 if (!info
|| !info
->attr
)
1099 return RMAP_NOMATCH
;
1101 ifp
= if_lookup_by_name_all_vrf ((char *)rule
);
1103 if (ifp
== NULL
|| ifp
->ifindex
!= info
->attr
->nh_ifindex
)
1104 return RMAP_NOMATCH
;
1108 return RMAP_NOMATCH
;
1111 /* Route map `interface' match statement. `arg' should be
1114 route_match_interface_compile (const char *arg
)
1116 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1119 /* Free route map's compiled `interface' value. */
1121 route_match_interface_free (void *rule
)
1123 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1126 /* Route map commands for ip address matching. */
1127 struct route_map_rule_cmd route_match_interface_cmd
=
1130 route_match_interface
,
1131 route_match_interface_compile
,
1132 route_match_interface_free
1137 /* `set ip next-hop IP_ADDRESS' */
1139 /* Match function return 1 if match is success else return zero. */
1140 static route_map_result_t
1141 route_match_tag (void *rule
, struct prefix
*prefix
,
1142 route_map_object_t type
, void *object
)
1145 struct bgp_info
*bgp_info
;
1147 if (type
== RMAP_BGP
)
1152 if (!bgp_info
->attr
->extra
)
1153 return RMAP_NOMATCH
;
1155 return ((bgp_info
->attr
->extra
->tag
== *tag
)? RMAP_MATCH
: RMAP_NOMATCH
);
1158 return RMAP_NOMATCH
;
1162 /* Route map commands for tag matching. */
1163 static struct route_map_rule_cmd route_match_tag_cmd
=
1167 route_map_rule_tag_compile
,
1168 route_map_rule_tag_free
,
1172 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1173 struct rmap_ip_nexthop_set
1175 struct in_addr
*address
;
1180 static route_map_result_t
1181 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
1182 route_map_object_t type
, void *object
)
1184 struct rmap_ip_nexthop_set
*rins
= rule
;
1185 struct bgp_info
*bgp_info
;
1188 if (type
== RMAP_BGP
)
1191 peer
= bgp_info
->peer
;
1193 if (rins
->unchanged
)
1195 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1196 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1198 else if (rins
->peer_address
)
1200 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
1201 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1203 && sockunion_family (peer
->su_remote
) == AF_INET
)
1205 bgp_info
->attr
->nexthop
.s_addr
= sockunion2ip (peer
->su_remote
);
1206 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1208 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
1210 /* The next hop value will be set as part of packet rewrite.
1211 * Set the flags here to indicate that rewrite needs to be done.
1212 * Also, clear the value.
1214 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1215 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1216 bgp_info
->attr
->nexthop
.s_addr
= 0;
1221 /* Set next hop value. */
1222 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1223 bgp_info
->attr
->nexthop
= *rins
->address
;
1224 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1225 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1232 /* Route map `ip nexthop' compile function. Given string is converted
1233 to struct in_addr structure. */
1235 route_set_ip_nexthop_compile (const char *arg
)
1237 struct rmap_ip_nexthop_set
*rins
;
1238 struct in_addr
*address
= NULL
;
1239 int peer_address
= 0;
1243 if (strcmp (arg
, "peer-address") == 0)
1245 else if (strcmp (arg
, "unchanged") == 0)
1249 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
1250 ret
= inet_aton (arg
, address
);
1254 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
1259 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_ip_nexthop_set
));
1261 rins
->address
= address
;
1262 rins
->peer_address
= peer_address
;
1263 rins
->unchanged
= unchanged
;
1268 /* Free route map's compiled `ip nexthop' value. */
1270 route_set_ip_nexthop_free (void *rule
)
1272 struct rmap_ip_nexthop_set
*rins
= rule
;
1275 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1277 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
);
1280 /* Route map commands for ip nexthop set. */
1281 struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
1284 route_set_ip_nexthop
,
1285 route_set_ip_nexthop_compile
,
1286 route_set_ip_nexthop_free
1289 /* `set local-preference LOCAL_PREF' */
1291 /* Set local preference. */
1292 static route_map_result_t
1293 route_set_local_pref (void *rule
, struct prefix
*prefix
,
1294 route_map_object_t type
, void *object
)
1296 struct rmap_value
*rv
;
1297 struct bgp_info
*bgp_info
;
1298 u_int32_t locpref
= 0;
1300 if (type
== RMAP_BGP
)
1302 /* Fetch routemap's rule information. */
1306 /* Set local preference value. */
1307 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
1308 locpref
= bgp_info
->attr
->local_pref
;
1310 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1311 bgp_info
->attr
->local_pref
= route_value_adjust(rv
, locpref
, bgp_info
->peer
);
1317 /* Set local preference rule structure. */
1318 struct route_map_rule_cmd route_set_local_pref_cmd
=
1321 route_set_local_pref
,
1322 route_value_compile
,
1326 /* `set weight WEIGHT' */
1329 static route_map_result_t
1330 route_set_weight (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
1333 struct rmap_value
*rv
;
1334 struct bgp_info
*bgp_info
;
1337 if (type
== RMAP_BGP
)
1339 /* Fetch routemap's rule information. */
1343 /* Set weight value. */
1344 weight
= route_value_adjust(rv
, 0, bgp_info
->peer
);
1346 (bgp_attr_extra_get (bgp_info
->attr
))->weight
= weight
;
1347 else if (bgp_info
->attr
->extra
)
1348 bgp_info
->attr
->extra
->weight
= 0;
1354 /* Set local preference rule structure. */
1355 struct route_map_rule_cmd route_set_weight_cmd
=
1359 route_value_compile
,
1363 /* `set metric METRIC' */
1365 /* Set metric to attribute. */
1366 static route_map_result_t
1367 route_set_metric (void *rule
, struct prefix
*prefix
,
1368 route_map_object_t type
, void *object
)
1370 struct rmap_value
*rv
;
1371 struct bgp_info
*bgp_info
;
1374 if (type
== RMAP_BGP
)
1376 /* Fetch routemap's rule information. */
1380 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1381 med
= bgp_info
->attr
->med
;
1383 bgp_info
->attr
->med
= route_value_adjust(rv
, med
, bgp_info
->peer
);
1384 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
1389 /* Set metric rule structure. */
1390 struct route_map_rule_cmd route_set_metric_cmd
=
1394 route_value_compile
,
1398 /* `set as-path prepend ASPATH' */
1400 /* For AS path prepend mechanism. */
1401 static route_map_result_t
1402 route_set_aspath_prepend (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1404 struct aspath
*aspath
;
1406 struct bgp_info
*binfo
;
1408 if (type
== RMAP_BGP
)
1412 if (binfo
->attr
->aspath
->refcnt
)
1413 new = aspath_dup (binfo
->attr
->aspath
);
1415 new = binfo
->attr
->aspath
;
1417 if ((uintptr_t)rule
> 10)
1420 aspath_prepend (aspath
, new);
1424 as_t as
= aspath_leftmost(new);
1425 if (!as
) as
= binfo
->peer
->as
;
1426 new = aspath_add_seq_n (new, as
, (uintptr_t) rule
);
1429 binfo
->attr
->aspath
= new;
1436 route_set_aspath_prepend_compile (const char *arg
)
1440 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
<= 10)
1441 return (void*)(uintptr_t)num
;
1443 return route_aspath_compile(arg
);
1447 route_set_aspath_prepend_free (void *rule
)
1449 if ((uintptr_t)rule
> 10)
1450 route_aspath_free(rule
);
1454 /* Set as-path prepend rule structure. */
1455 struct route_map_rule_cmd route_set_aspath_prepend_cmd
=
1458 route_set_aspath_prepend
,
1459 route_set_aspath_prepend_compile
,
1460 route_set_aspath_prepend_free
,
1463 /* `set as-path exclude ASn' */
1465 /* For ASN exclude mechanism.
1466 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1467 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1469 static route_map_result_t
1470 route_set_aspath_exclude (void *rule
, struct prefix
*dummy
, route_map_object_t type
, void *object
)
1472 struct aspath
* new_path
, * exclude_path
;
1473 struct bgp_info
*binfo
;
1475 if (type
== RMAP_BGP
)
1477 exclude_path
= rule
;
1479 if (binfo
->attr
->aspath
->refcnt
)
1480 new_path
= aspath_dup (binfo
->attr
->aspath
);
1482 new_path
= binfo
->attr
->aspath
;
1483 binfo
->attr
->aspath
= aspath_filter_exclude (new_path
, exclude_path
);
1488 /* Set ASn exlude rule structure. */
1489 struct route_map_rule_cmd route_set_aspath_exclude_cmd
=
1492 route_set_aspath_exclude
,
1493 route_aspath_compile
,
1497 /* `set community COMMUNITY' */
1500 struct community
*com
;
1505 /* For community set mechanism. */
1506 static route_map_result_t
1507 route_set_community (void *rule
, struct prefix
*prefix
,
1508 route_map_object_t type
, void *object
)
1510 struct rmap_com_set
*rcs
;
1511 struct bgp_info
*binfo
;
1513 struct community
*new = NULL
;
1514 struct community
*old
;
1515 struct community
*merge
;
1517 if (type
== RMAP_BGP
)
1522 old
= attr
->community
;
1527 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
));
1528 attr
->community
= NULL
;
1529 /* See the longer comment down below. */
1530 if (old
&& old
->refcnt
== 0)
1531 community_free(old
);
1535 /* "additive" case. */
1536 if (rcs
->additive
&& old
)
1538 merge
= community_merge (community_dup (old
), rcs
->com
);
1540 /* HACK: if the old community is not intern'd,
1541 * we should free it here, or all reference to it may be lost.
1542 * Really need to cleanup attribute caching sometime.
1544 if (old
->refcnt
== 0)
1545 community_free (old
);
1546 new = community_uniq_sort (merge
);
1547 community_free (merge
);
1550 new = community_dup (rcs
->com
);
1552 /* will be interned by caller if required */
1553 attr
->community
= new;
1555 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1561 /* Compile function for set community. */
1563 route_set_community_compile (const char *arg
)
1565 struct rmap_com_set
*rcs
;
1566 struct community
*com
= NULL
;
1571 if (strcmp (arg
, "none") == 0)
1575 sp
= strstr (arg
, "additive");
1579 /* "additive" keyworkd is included. */
1584 com
= community_str2com (arg
);
1593 rcs
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_com_set
));
1595 rcs
->additive
= additive
;
1601 /* Free function for set community. */
1603 route_set_community_free (void *rule
)
1605 struct rmap_com_set
*rcs
= rule
;
1608 community_free (rcs
->com
);
1609 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1612 /* Set community rule structure. */
1613 struct route_map_rule_cmd route_set_community_cmd
=
1616 route_set_community
,
1617 route_set_community_compile
,
1618 route_set_community_free
,
1621 /* `set community COMMUNITY' */
1622 struct rmap_lcom_set
1624 struct lcommunity
*lcom
;
1630 /* For lcommunity set mechanism. */
1631 static route_map_result_t
1632 route_set_lcommunity (void *rule
, struct prefix
*prefix
,
1633 route_map_object_t type
, void *object
)
1635 struct rmap_lcom_set
*rcs
;
1636 struct bgp_info
*binfo
;
1638 struct lcommunity
*new = NULL
;
1639 struct lcommunity
*old
;
1640 struct lcommunity
*merge
;
1642 if (type
== RMAP_BGP
)
1647 old
= (attr
->extra
) ? attr
->extra
->lcommunity
: NULL
;
1652 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
));
1654 attr
->extra
->lcommunity
= NULL
;
1656 /* See the longer comment down below. */
1657 if (old
&& old
->refcnt
== 0)
1658 lcommunity_free(&old
);
1662 if (rcs
->additive
&& old
)
1664 merge
= lcommunity_merge (lcommunity_dup (old
), rcs
->lcom
);
1666 /* HACK: if the old large-community is not intern'd,
1667 * we should free it here, or all reference to it may be lost.
1668 * Really need to cleanup attribute caching sometime.
1670 if (old
->refcnt
== 0)
1671 lcommunity_free (&old
);
1672 new = lcommunity_uniq_sort (merge
);
1673 lcommunity_free (&merge
);
1676 new = lcommunity_dup (rcs
->lcom
);
1678 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1679 (bgp_attr_extra_get (attr
))->lcommunity
= new;
1681 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
);
1687 /* Compile function for set community. */
1689 route_set_lcommunity_compile (const char *arg
)
1691 struct rmap_lcom_set
*rcs
;
1692 struct lcommunity
*lcom
= NULL
;
1697 if (strcmp (arg
, "none") == 0)
1701 sp
= strstr (arg
, "additive");
1705 /* "additive" keyworkd is included. */
1710 lcom
= lcommunity_str2com (arg
);
1719 rcs
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_com_set
));
1721 rcs
->additive
= additive
;
1727 /* Free function for set lcommunity. */
1729 route_set_lcommunity_free (void *rule
)
1731 struct rmap_lcom_set
*rcs
= rule
;
1734 lcommunity_free (&rcs
->lcom
);
1736 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1739 /* Set community rule structure. */
1740 struct route_map_rule_cmd route_set_lcommunity_cmd
=
1743 route_set_lcommunity
,
1744 route_set_lcommunity_compile
,
1745 route_set_lcommunity_free
,
1748 /* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
1750 /* For large community set mechanism. */
1751 static route_map_result_t
1752 route_set_lcommunity_delete (void *rule
, struct prefix
*prefix
,
1753 route_map_object_t type
, void *object
)
1755 struct community_list
*list
;
1756 struct lcommunity
*merge
;
1757 struct lcommunity
*new;
1758 struct lcommunity
*old
;
1759 struct bgp_info
*binfo
;
1761 if (type
== RMAP_BGP
)
1767 list
= community_list_lookup (bgp_clist
, rule
,
1768 LARGE_COMMUNITY_LIST_MASTER
);
1769 old
= ((binfo
->attr
->extra
) ? binfo
->attr
->extra
->lcommunity
: NULL
);
1773 merge
= lcommunity_list_match_delete (lcommunity_dup (old
), list
);
1774 new = lcommunity_uniq_sort (merge
);
1775 lcommunity_free (&merge
);
1777 /* HACK: if the old community is not intern'd,
1778 * we should free it here, or all reference to it may be lost.
1779 * Really need to cleanup attribute caching sometime.
1781 if (old
->refcnt
== 0)
1782 lcommunity_free (&old
);
1786 binfo
->attr
->extra
->lcommunity
= NULL
;
1787 binfo
->attr
->flag
&= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
);
1788 lcommunity_free (&new);
1792 binfo
->attr
->extra
->lcommunity
= new;
1793 binfo
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
);
1801 /* Compile function for set lcommunity. */
1803 route_set_lcommunity_delete_compile (const char *arg
)
1809 p
= strchr (arg
, ' ');
1813 str
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1814 memcpy (str
, arg
, len
);
1822 /* Free function for set lcommunity. */
1824 route_set_lcommunity_delete_free (void *rule
)
1826 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1829 /* Set lcommunity rule structure. */
1830 struct route_map_rule_cmd route_set_lcommunity_delete_cmd
=
1833 route_set_lcommunity_delete
,
1834 route_set_lcommunity_delete_compile
,
1835 route_set_lcommunity_delete_free
,
1839 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
1841 /* For community set mechanism. */
1842 static route_map_result_t
1843 route_set_community_delete (void *rule
, struct prefix
*prefix
,
1844 route_map_object_t type
, void *object
)
1846 struct community_list
*list
;
1847 struct community
*merge
;
1848 struct community
*new;
1849 struct community
*old
;
1850 struct bgp_info
*binfo
;
1852 if (type
== RMAP_BGP
)
1858 list
= community_list_lookup (bgp_clist
, rule
, COMMUNITY_LIST_MASTER
);
1859 old
= binfo
->attr
->community
;
1863 merge
= community_list_match_delete (community_dup (old
), list
);
1864 new = community_uniq_sort (merge
);
1865 community_free (merge
);
1867 /* HACK: if the old community is not intern'd,
1868 * we should free it here, or all reference to it may be lost.
1869 * Really need to cleanup attribute caching sometime.
1871 if (old
->refcnt
== 0)
1872 community_free (old
);
1876 binfo
->attr
->community
= NULL
;
1877 binfo
->attr
->flag
&= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1878 community_free (new);
1882 binfo
->attr
->community
= new;
1883 binfo
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1891 /* Compile function for set community. */
1893 route_set_community_delete_compile (const char *arg
)
1899 p
= strchr (arg
, ' ');
1903 str
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1904 memcpy (str
, arg
, len
);
1912 /* Free function for set community. */
1914 route_set_community_delete_free (void *rule
)
1916 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1919 /* Set community rule structure. */
1920 struct route_map_rule_cmd route_set_community_delete_cmd
=
1923 route_set_community_delete
,
1924 route_set_community_delete_compile
,
1925 route_set_community_delete_free
,
1928 /* `set extcommunity rt COMMUNITY' */
1930 /* For community set mechanism. Used by _rt and _soo. */
1931 static route_map_result_t
1932 route_set_ecommunity (void *rule
, struct prefix
*prefix
,
1933 route_map_object_t type
, void *object
)
1935 struct ecommunity
*ecom
;
1936 struct ecommunity
*new_ecom
;
1937 struct ecommunity
*old_ecom
;
1938 struct bgp_info
*bgp_info
;
1940 if (type
== RMAP_BGP
)
1948 /* We assume additive for Extended Community. */
1949 old_ecom
= (bgp_attr_extra_get (bgp_info
->attr
))->ecommunity
;
1953 new_ecom
= ecommunity_merge (ecommunity_dup (old_ecom
), ecom
);
1955 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1956 * ->refcnt = 0 => set by a previous route-map statement */
1957 if (!old_ecom
->refcnt
)
1958 ecommunity_free (&old_ecom
);
1961 new_ecom
= ecommunity_dup (ecom
);
1963 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1964 bgp_info
->attr
->extra
->ecommunity
= new_ecom
;
1966 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
);
1971 /* Compile function for set community. */
1973 route_set_ecommunity_rt_compile (const char *arg
)
1975 struct ecommunity
*ecom
;
1977 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
1980 return ecommunity_intern (ecom
);
1983 /* Free function for set community. Used by _rt and _soo */
1985 route_set_ecommunity_free (void *rule
)
1987 struct ecommunity
*ecom
= rule
;
1988 ecommunity_unintern (&ecom
);
1991 /* Set community rule structure. */
1992 struct route_map_rule_cmd route_set_ecommunity_rt_cmd
=
1995 route_set_ecommunity
,
1996 route_set_ecommunity_rt_compile
,
1997 route_set_ecommunity_free
,
2000 /* `set extcommunity soo COMMUNITY' */
2002 /* Compile function for set community. */
2004 route_set_ecommunity_soo_compile (const char *arg
)
2006 struct ecommunity
*ecom
;
2008 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
2012 return ecommunity_intern (ecom
);
2015 /* Set community rule structure. */
2016 struct route_map_rule_cmd route_set_ecommunity_soo_cmd
=
2019 route_set_ecommunity
,
2020 route_set_ecommunity_soo_compile
,
2021 route_set_ecommunity_free
,
2024 /* `set origin ORIGIN' */
2026 /* For origin set. */
2027 static route_map_result_t
2028 route_set_origin (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
2031 struct bgp_info
*bgp_info
;
2033 if (type
== RMAP_BGP
)
2038 bgp_info
->attr
->origin
= *origin
;
2044 /* Compile function for origin set. */
2046 route_set_origin_compile (const char *arg
)
2050 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
2052 if (strcmp (arg
, "igp") == 0)
2054 else if (strcmp (arg
, "egp") == 0)
2062 /* Compile function for origin set. */
2064 route_set_origin_free (void *rule
)
2066 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2069 /* Set origin rule structure. */
2070 struct route_map_rule_cmd route_set_origin_cmd
=
2074 route_set_origin_compile
,
2075 route_set_origin_free
,
2078 /* `set atomic-aggregate' */
2080 /* For atomic aggregate set. */
2081 static route_map_result_t
2082 route_set_atomic_aggregate (void *rule
, struct prefix
*prefix
,
2083 route_map_object_t type
, void *object
)
2085 struct bgp_info
*bgp_info
;
2087 if (type
== RMAP_BGP
)
2090 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
2096 /* Compile function for atomic aggregate. */
2098 route_set_atomic_aggregate_compile (const char *arg
)
2103 /* Compile function for atomic aggregate. */
2105 route_set_atomic_aggregate_free (void *rule
)
2110 /* Set atomic aggregate rule structure. */
2111 struct route_map_rule_cmd route_set_atomic_aggregate_cmd
=
2114 route_set_atomic_aggregate
,
2115 route_set_atomic_aggregate_compile
,
2116 route_set_atomic_aggregate_free
,
2119 /* `set aggregator as AS A.B.C.D' */
2123 struct in_addr address
;
2126 static route_map_result_t
2127 route_set_aggregator_as (void *rule
, struct prefix
*prefix
,
2128 route_map_object_t type
, void *object
)
2130 struct bgp_info
*bgp_info
;
2131 struct aggregator
*aggregator
;
2132 struct attr_extra
*ae
;
2134 if (type
== RMAP_BGP
)
2138 ae
= bgp_attr_extra_get (bgp_info
->attr
);
2140 ae
->aggregator_as
= aggregator
->as
;
2141 ae
->aggregator_addr
= aggregator
->address
;
2142 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
);
2149 route_set_aggregator_as_compile (const char *arg
)
2151 struct aggregator
*aggregator
;
2155 aggregator
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct aggregator
));
2156 sscanf (arg
, "%s %s", as
, address
);
2158 aggregator
->as
= strtoul (as
, NULL
, 10);
2159 inet_aton (address
, &aggregator
->address
);
2165 route_set_aggregator_as_free (void *rule
)
2167 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2170 struct route_map_rule_cmd route_set_aggregator_as_cmd
=
2173 route_set_aggregator_as
,
2174 route_set_aggregator_as_compile
,
2175 route_set_aggregator_as_free
,
2178 /* Set tag to object. object must be pointer to struct bgp_info */
2179 static route_map_result_t
2180 route_set_tag (void *rule
, struct prefix
*prefix
,
2181 route_map_object_t type
, void *object
)
2184 struct bgp_info
*bgp_info
;
2185 struct attr_extra
*ae
;
2187 if (type
== RMAP_BGP
)
2191 ae
= bgp_attr_extra_get (bgp_info
->attr
);
2201 /* Route map commands for tag set. */
2202 static struct route_map_rule_cmd route_set_tag_cmd
=
2206 route_map_rule_tag_compile
,
2207 route_map_rule_tag_free
,
2211 /* `match ipv6 address IP_ACCESS_LIST' */
2213 static route_map_result_t
2214 route_match_ipv6_address (void *rule
, struct prefix
*prefix
,
2215 route_map_object_t type
, void *object
)
2217 struct access_list
*alist
;
2219 if (type
== RMAP_BGP
)
2221 alist
= access_list_lookup (AFI_IP6
, (char *) rule
);
2223 return RMAP_NOMATCH
;
2225 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
2226 RMAP_NOMATCH
: RMAP_MATCH
);
2228 return RMAP_NOMATCH
;
2232 route_match_ipv6_address_compile (const char *arg
)
2234 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2238 route_match_ipv6_address_free (void *rule
)
2240 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2243 /* Route map commands for ip address matching. */
2244 struct route_map_rule_cmd route_match_ipv6_address_cmd
=
2247 route_match_ipv6_address
,
2248 route_match_ipv6_address_compile
,
2249 route_match_ipv6_address_free
2252 /* `match ipv6 next-hop IP_ADDRESS' */
2254 static route_map_result_t
2255 route_match_ipv6_next_hop (void *rule
, struct prefix
*prefix
,
2256 route_map_object_t type
, void *object
)
2258 struct in6_addr
*addr
= rule
;
2259 struct bgp_info
*bgp_info
;
2261 if (type
== RMAP_BGP
)
2265 if (!bgp_info
->attr
->extra
)
2266 return RMAP_NOMATCH
;
2268 if (IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_global
, addr
))
2271 if (bgp_info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
&&
2272 IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_local
, rule
))
2275 return RMAP_NOMATCH
;
2278 return RMAP_NOMATCH
;
2282 route_match_ipv6_next_hop_compile (const char *arg
)
2284 struct in6_addr
*address
;
2287 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2289 ret
= inet_pton (AF_INET6
, arg
, address
);
2292 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2300 route_match_ipv6_next_hop_free (void *rule
)
2302 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2305 struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
=
2308 route_match_ipv6_next_hop
,
2309 route_match_ipv6_next_hop_compile
,
2310 route_match_ipv6_next_hop_free
2313 /* `match ipv6 address prefix-list PREFIX_LIST' */
2315 static route_map_result_t
2316 route_match_ipv6_address_prefix_list (void *rule
, struct prefix
*prefix
,
2317 route_map_object_t type
, void *object
)
2319 struct prefix_list
*plist
;
2321 if (type
== RMAP_BGP
)
2323 plist
= prefix_list_lookup (AFI_IP6
, (char *) rule
);
2325 return RMAP_NOMATCH
;
2327 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
2328 RMAP_NOMATCH
: RMAP_MATCH
);
2330 return RMAP_NOMATCH
;
2334 route_match_ipv6_address_prefix_list_compile (const char *arg
)
2336 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2340 route_match_ipv6_address_prefix_list_free (void *rule
)
2342 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2345 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
=
2347 "ipv6 address prefix-list",
2348 route_match_ipv6_address_prefix_list
,
2349 route_match_ipv6_address_prefix_list_compile
,
2350 route_match_ipv6_address_prefix_list_free
2353 /* `set ipv6 nexthop global IP_ADDRESS' */
2355 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2356 static route_map_result_t
2357 route_set_ipv6_nexthop_global (void *rule
, struct prefix
*prefix
,
2358 route_map_object_t type
, void *object
)
2360 struct in6_addr
*address
;
2361 struct bgp_info
*bgp_info
;
2363 if (type
== RMAP_BGP
)
2365 /* Fetch routemap's rule information. */
2369 /* Set next hop value. */
2370 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= *address
;
2372 /* Set nexthop length. */
2373 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2374 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
2376 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2377 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
2383 /* Route map `ip next-hop' compile function. Given string is converted
2384 to struct in_addr structure. */
2386 route_set_ipv6_nexthop_global_compile (const char *arg
)
2389 struct in6_addr
*address
;
2391 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2393 ret
= inet_pton (AF_INET6
, arg
, address
);
2397 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2404 /* Free route map's compiled `ip next-hop' value. */
2406 route_set_ipv6_nexthop_global_free (void *rule
)
2408 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2411 /* Route map commands for ip nexthop set. */
2412 struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd
=
2414 "ipv6 next-hop global",
2415 route_set_ipv6_nexthop_global
,
2416 route_set_ipv6_nexthop_global_compile
,
2417 route_set_ipv6_nexthop_global_free
2420 /* Set next-hop preference value. */
2421 static route_map_result_t
2422 route_set_ipv6_nexthop_prefer_global (void *rule
, struct prefix
*prefix
,
2423 route_map_object_t type
, void *object
)
2425 struct bgp_info
*bgp_info
;
2428 if (type
== RMAP_BGP
)
2430 /* Fetch routemap's rule information. */
2432 peer
= bgp_info
->peer
;
2434 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2435 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2437 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2439 /* Set next hop preference to global */
2440 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= TRUE
;
2441 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2442 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2446 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= FALSE
;
2447 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2448 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2455 route_set_ipv6_nexthop_prefer_global_compile (const char *arg
)
2459 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2465 /* Free route map's compiled `ip next-hop' value. */
2467 route_set_ipv6_nexthop_prefer_global_free (void *rule
)
2469 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2472 /* Route map commands for ip nexthop set preferred. */
2473 struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd
=
2475 "ipv6 next-hop prefer-global",
2476 route_set_ipv6_nexthop_prefer_global
,
2477 route_set_ipv6_nexthop_prefer_global_compile
,
2478 route_set_ipv6_nexthop_prefer_global_free
2481 /* `set ipv6 nexthop local IP_ADDRESS' */
2483 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2484 static route_map_result_t
2485 route_set_ipv6_nexthop_local (void *rule
, struct prefix
*prefix
,
2486 route_map_object_t type
, void *object
)
2488 struct in6_addr
*address
;
2489 struct bgp_info
*bgp_info
;
2491 if (type
== RMAP_BGP
)
2493 /* Fetch routemap's rule information. */
2497 /* Set next hop value. */
2498 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= *address
;
2500 /* Set nexthop length. */
2501 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
2502 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
2504 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2505 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
2511 /* Route map `ip nexthop' compile function. Given string is converted
2512 to struct in_addr structure. */
2514 route_set_ipv6_nexthop_local_compile (const char *arg
)
2517 struct in6_addr
*address
;
2519 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2521 ret
= inet_pton (AF_INET6
, arg
, address
);
2525 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2532 /* Free route map's compiled `ip nexthop' value. */
2534 route_set_ipv6_nexthop_local_free (void *rule
)
2536 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2539 /* Route map commands for ip nexthop set. */
2540 struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
2542 "ipv6 next-hop local",
2543 route_set_ipv6_nexthop_local
,
2544 route_set_ipv6_nexthop_local_compile
,
2545 route_set_ipv6_nexthop_local_free
2548 /* `set ipv6 nexthop peer-address' */
2550 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2551 static route_map_result_t
2552 route_set_ipv6_nexthop_peer (void *rule
, struct prefix
*prefix
,
2553 route_map_object_t type
, void *object
)
2555 struct in6_addr peer_address
;
2556 struct bgp_info
*bgp_info
;
2559 if (type
== RMAP_BGP
)
2561 /* Fetch routemap's rule information. */
2563 peer
= bgp_info
->peer
;
2565 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2566 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2568 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2570 peer_address
= peer
->su_remote
->sin6
.sin6_addr
;
2571 /* Set next hop value and length in attribute. */
2572 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
))
2574 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= peer_address
;
2575 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= 32)
2576 bgp_info
->attr
->extra
->mp_nexthop_len
= 32;
2580 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= peer_address
;
2581 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2582 bgp_info
->attr
->extra
->mp_nexthop_len
= 16;
2586 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
2588 /* The next hop value will be set as part of packet rewrite.
2589 * Set the flags here to indicate that rewrite needs to be done.
2590 * Also, clear the value - we clear both global and link-local
2591 * nexthops, whether we send one or both is determined elsewhere.
2593 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2594 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
2595 /* clear next hop value. */
2596 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
),
2597 0, sizeof (struct in6_addr
));
2598 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
),
2599 0, sizeof (struct in6_addr
));
2606 /* Route map `ip next-hop' compile function. Given string is converted
2607 to struct in_addr structure. */
2609 route_set_ipv6_nexthop_peer_compile (const char *arg
)
2613 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2619 /* Free route map's compiled `ip next-hop' value. */
2621 route_set_ipv6_nexthop_peer_free (void *rule
)
2623 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2626 /* Route map commands for ip nexthop set. */
2627 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
=
2629 "ipv6 next-hop peer-address",
2630 route_set_ipv6_nexthop_peer
,
2631 route_set_ipv6_nexthop_peer_compile
,
2632 route_set_ipv6_nexthop_peer_free
2635 /* `set ip vpn nexthop A.B.C.D' */
2637 static route_map_result_t
2638 route_set_vpnv4_nexthop (void *rule
, struct prefix
*prefix
,
2639 route_map_object_t type
, void *object
)
2641 struct in_addr
*address
;
2642 struct bgp_info
*bgp_info
;
2644 if (type
== RMAP_BGP
)
2646 /* Fetch routemap's rule information. */
2650 /* Set next hop value. */
2651 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global_in
= *address
;
2652 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_len
= 4;
2659 route_set_vpnv4_nexthop_compile (const char *arg
)
2662 struct in_addr
*address
;
2664 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2666 ret
= inet_aton (arg
, address
);
2670 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2677 /* `set ipv6 vpn nexthop A.B.C.D' */
2679 static route_map_result_t
2680 route_set_vpnv6_nexthop (void *rule
, struct prefix
*prefix
,
2681 route_map_object_t type
, void *object
)
2683 struct in6_addr
*address
;
2684 struct bgp_info
*bgp_info
;
2686 if (type
== RMAP_BGP
)
2688 /* Fetch routemap's rule information. */
2692 /* Set next hop value. */
2693 memcpy (&(bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
, address
, sizeof(struct in6_addr
));
2694 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_len
= BGP_ATTR_NHLEN_VPNV6_GLOBAL
;
2701 route_set_vpnv6_nexthop_compile (const char *arg
)
2704 struct in6_addr
*address
;
2706 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2707 ret
= inet_pton (AF_INET6
, arg
, address
);
2711 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2719 route_set_vpn_nexthop_free (void *rule
)
2721 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2724 /* Route map commands for ip nexthop set. */
2725 struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
=
2728 route_set_vpnv4_nexthop
,
2729 route_set_vpnv4_nexthop_compile
,
2730 route_set_vpn_nexthop_free
2733 /* Route map commands for ip nexthop set. */
2734 struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd
=
2736 "ipv6 vpn next-hop",
2737 route_set_vpnv6_nexthop
,
2738 route_set_vpnv6_nexthop_compile
,
2739 route_set_vpn_nexthop_free
2742 /* `set originator-id' */
2744 /* For origin set. */
2745 static route_map_result_t
2746 route_set_originator_id (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
2748 struct in_addr
*address
;
2749 struct bgp_info
*bgp_info
;
2751 if (type
== RMAP_BGP
)
2756 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
);
2757 (bgp_attr_extra_get (bgp_info
->attr
))->originator_id
= *address
;
2763 /* Compile function for originator-id set. */
2765 route_set_originator_id_compile (const char *arg
)
2768 struct in_addr
*address
;
2770 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2772 ret
= inet_aton (arg
, address
);
2776 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2783 /* Compile function for originator_id set. */
2785 route_set_originator_id_free (void *rule
)
2787 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2790 /* Set originator-id rule structure. */
2791 struct route_map_rule_cmd route_set_originator_id_cmd
=
2794 route_set_originator_id
,
2795 route_set_originator_id_compile
,
2796 route_set_originator_id_free
,
2799 /* Add bgp route map rule. */
2801 bgp_route_match_add (struct vty
*vty
,
2802 const char *command
, const char *arg
,
2803 route_map_event_t type
)
2805 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
2808 ret
= route_map_add_match (index
, command
, arg
);
2813 case RMAP_RULE_MISSING
:
2814 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2816 case RMAP_COMPILE_ERROR
:
2817 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2822 if (type
!= RMAP_EVENT_MATCH_ADDED
)
2824 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
2830 /* Delete bgp route map rule. */
2832 bgp_route_match_delete (struct vty
*vty
,
2833 const char *command
, const char *arg
,
2834 route_map_event_t type
)
2836 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
2838 char *dep_name
= NULL
;
2840 char *rmap_name
= NULL
;
2842 if (type
!= RMAP_EVENT_MATCH_DELETED
)
2844 /* ignore the mundane, the types without any dependency */
2847 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
2848 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
2852 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
2854 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
2857 ret
= route_map_delete_match (index
, command
, dep_name
);
2862 case RMAP_RULE_MISSING
:
2863 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2865 case RMAP_COMPILE_ERROR
:
2866 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2870 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2872 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2876 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
2877 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
2880 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2882 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2888 * This is the workhorse routine for processing in/out routemap
2892 bgp_route_map_process_peer (const char *rmap_name
, struct route_map
*map
,
2893 struct peer
*peer
, int afi
, int safi
,
2898 struct bgp_filter
*filter
;
2900 if (!peer
|| !rmap_name
)
2903 filter
= &peer
->filter
[afi
][safi
];
2905 * in is for non-route-server clients,
2906 * out is for all peers
2908 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2910 if (filter
->map
[RMAP_IN
].name
&&
2911 (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0))
2913 filter
->map
[RMAP_IN
].map
= map
;
2915 if (route_update
&& peer
->status
== Established
)
2917 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2918 PEER_FLAG_SOFT_RECONFIG
))
2920 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2921 zlog_debug("Processing route_map %s update on "
2922 "peer %s (inbound, soft-reconfig)",
2923 rmap_name
, peer
->host
);
2925 bgp_soft_reconfig_in (peer
, afi
, safi
);
2927 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2928 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2931 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2932 zlog_debug("Processing route_map %s update on "
2933 "peer %s (inbound, route-refresh)",
2934 rmap_name
, peer
->host
);
2935 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2941 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2945 if (update
&& route_update
&& peer
->status
== Established
)
2947 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2948 PEER_FLAG_SOFT_RECONFIG
))
2950 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2951 zlog_debug("Processing route_map %s update on "
2952 "peer %s (import, soft-reconfig)",
2953 rmap_name
, peer
->host
);
2955 bgp_soft_reconfig_in (peer
, afi
, safi
);
2957 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2958 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2960 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2961 zlog_debug("Processing route_map %s update on "
2962 "peer %s (import, route-refresh)",
2963 rmap_name
, peer
->host
);
2964 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2966 /* DD: Else, what else do we do ? Reset peer ? */
2971 * For outbound, unsuppress and default-originate map change (content or
2972 * map created), merely update the "config" here, the actual route
2973 * announcement happens at the group level.
2975 if (filter
->map
[RMAP_OUT
].name
&&
2976 (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
2977 filter
->map
[RMAP_OUT
].map
= map
;
2979 if (filter
->usmap
.name
&&
2980 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
2981 filter
->usmap
.map
= map
;
2983 if (peer
->default_rmap
[afi
][safi
].name
&&
2984 (strcmp (rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
2985 peer
->default_rmap
[afi
][safi
].map
= map
;
2989 bgp_route_map_update_peer_group(const char *rmap_name
, struct route_map
*map
,
2992 struct peer_group
*group
;
2993 struct listnode
*node
, *nnode
;
2994 struct bgp_filter
*filter
;
3001 /* All the peers have been updated correctly already. This is
3002 * just updating the placeholder data. No real update required.
3004 for (ALL_LIST_ELEMENTS (bgp
->group
, node
, nnode
, group
))
3005 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3006 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3008 filter
= &group
->conf
->filter
[afi
][safi
];
3010 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++)
3012 if ((filter
->map
[direct
].name
) &&
3013 (strcmp(rmap_name
, filter
->map
[direct
].name
) == 0))
3014 filter
->map
[direct
].map
= map
;
3017 if (filter
->usmap
.name
&&
3018 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3019 filter
->usmap
.map
= map
;
3024 * Note that if an extreme number (tens of thousands) of route-maps are in use
3025 * and if bgp has an extreme number of peers, network statements, etc then this
3026 * function can consume a lot of cycles. This is due to this function being
3027 * called for each route-map and within this function we walk the list of peers,
3028 * network statements, etc looking to see if they use this route-map.
3031 bgp_route_map_process_update (struct bgp
*bgp
, const char *rmap_name
, int route_update
)
3037 struct bgp_node
*bn
;
3038 struct bgp_static
*bgp_static
;
3039 struct listnode
*node
, *nnode
;
3040 struct route_map
*map
;
3041 char buf
[INET6_ADDRSTRLEN
];
3043 map
= route_map_lookup_by_name (rmap_name
);
3045 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
3048 /* Ignore dummy peer-group structure */
3049 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3052 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3053 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3055 /* Ignore inactive AFI/SAFI */
3056 if (! peer
->afc
[afi
][safi
])
3059 /* process in/out/import/export/default-orig route-maps */
3060 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
, safi
, route_update
);
3064 /* for outbound/default-orig route-maps, process for groups */
3065 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
3068 /* update peer-group config (template) */
3069 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
3071 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3072 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3074 /* For table route-map updates. */
3075 if (bgp
->table_map
[afi
][safi
].name
&&
3076 (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
) == 0))
3078 bgp
->table_map
[afi
][safi
].map
= map
;
3080 if (BGP_DEBUG (zebra
, ZEBRA
))
3081 zlog_debug("Processing route_map %s update on "
3082 "table map", rmap_name
);
3084 bgp_zebra_announce_table(bgp
, afi
, safi
);
3087 /* For network route-map updates. */
3088 for (bn
= bgp_table_top (bgp
->route
[afi
][safi
]); bn
; bn
= bgp_route_next (bn
))
3089 if ((bgp_static
= bn
->info
) != NULL
)
3091 if (bgp_static
->rmap
.name
&&
3092 (strcmp(rmap_name
, bgp_static
->rmap
.name
) == 0))
3094 bgp_static
->rmap
.map
= map
;
3097 if (!bgp_static
->backdoor
)
3099 if (bgp_debug_zebra(&bn
->p
))
3100 zlog_debug("Processing route_map %s update on "
3101 "static route %s", rmap_name
,
3102 inet_ntop (bn
->p
.family
, &bn
->p
.u
.prefix
,
3103 buf
, INET6_ADDRSTRLEN
));
3104 bgp_static_update (bgp
, &bn
->p
, bgp_static
, afi
, safi
);
3110 /* For redistribute route-map updates. */
3111 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3112 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3114 struct list
*red_list
;
3115 struct listnode
*node
;
3116 struct bgp_redist
*red
;
3118 red_list
= bgp
->redist
[afi
][i
];
3122 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
3124 if (red
->rmap
.name
&&
3125 (strcmp(rmap_name
, red
->rmap
.name
) == 0))
3127 red
->rmap
.map
= map
;
3131 if (BGP_DEBUG (zebra
, ZEBRA
))
3132 zlog_debug("Processing route_map %s update on "
3133 "redistributed routes", rmap_name
);
3135 bgp_redistribute_resend (bgp
, afi
, i
, red
->instance
);
3143 bgp_route_map_process_update_cb (char *rmap_name
)
3145 struct listnode
*node
, *nnode
;
3148 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
3149 bgp_route_map_process_update(bgp
, rmap_name
, 1);
3152 zlog_debug("%s: calling vnc_routemap_update", __func__
);
3153 vnc_routemap_update(bgp
, __func__
);
3159 bgp_route_map_update_timer(struct thread
*thread
)
3161 bm
->t_rmap_update
= NULL
;
3163 route_map_walk_update_list(bgp_route_map_process_update_cb
);
3169 bgp_route_map_mark_update (const char *rmap_name
)
3171 if (bm
->t_rmap_update
== NULL
)
3173 struct listnode
*node
, *nnode
;
3176 /* rmap_update_timer of 0 means don't do route updates */
3177 if (bm
->rmap_update_timer
)
3180 thread_add_timer(bm
->master
, bgp_route_map_update_timer
, NULL
,
3181 bm
->rmap_update_timer
);
3183 /* Signal the groups that a route-map update event has started */
3184 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
3185 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
, 1, 1);
3189 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
3190 bgp_route_map_process_update(bgp
, rmap_name
, 0);
3192 zlog_debug("%s: calling vnc_routemap_update", __func__
);
3193 vnc_routemap_update(bgp
, __func__
);
3200 bgp_route_map_add (const char *rmap_name
)
3202 if (route_map_mark_updated(rmap_name
, 0) == 0)
3203 bgp_route_map_mark_update(rmap_name
);
3205 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3209 bgp_route_map_delete (const char *rmap_name
)
3211 if (route_map_mark_updated(rmap_name
, 1) == 0)
3212 bgp_route_map_mark_update(rmap_name
);
3214 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
3218 bgp_route_map_event (route_map_event_t event
, const char *rmap_name
)
3220 if (route_map_mark_updated(rmap_name
, 0) == 0)
3221 bgp_route_map_mark_update(rmap_name
);
3223 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3229 "match peer <A.B.C.D|X:X::X:X>",
3231 "Match peer address\n"
3232 "IP address of peer\n"
3233 "IPv6 address of peer\n")
3236 return bgp_route_match_add (vty
, "peer", argv
[idx_ip
]->arg
,
3237 RMAP_EVENT_MATCH_ADDED
);
3240 DEFUN (match_peer_local
,
3241 match_peer_local_cmd
,
3244 "Match peer address\n"
3245 "Static or Redistributed routes\n")
3247 return bgp_route_match_add (vty
, "peer", "local",
3248 RMAP_EVENT_MATCH_DELETED
);
3251 DEFUN (no_match_peer
,
3253 "no match peer [<local|A.B.C.D|X:X::X:X>]",
3256 "Match peer address\n"
3257 "Static or Redistributed routes\n"
3258 "IP address of peer\n"
3259 "IPv6 address of peer\n")
3263 if (argc
<= idx_peer
)
3264 return bgp_route_match_delete (vty
, "peer", NULL
,
3265 RMAP_EVENT_MATCH_DELETED
);
3266 return bgp_route_match_delete (vty
, "peer", argv
[idx_peer
]->arg
,
3267 RMAP_EVENT_MATCH_DELETED
);
3271 /* match probability */
3272 DEFUN (match_probability
,
3273 match_probability_cmd
,
3274 "match probability (0-100)",
3276 "Match portion of routes defined by percentage value\n"
3277 "Percentage of routes\n")
3280 return bgp_route_match_add (vty
, "probability", argv
[idx_number
]->arg
,
3281 RMAP_EVENT_MATCH_ADDED
);
3285 DEFUN (no_match_probability
,
3286 no_match_probability_cmd
,
3287 "no match probability [(1-99)]",
3290 "Match portion of routes defined by percentage value\n"
3291 "Percentage of routes\n")
3294 if (argc
<= idx_number
)
3295 return bgp_route_match_delete (vty
, "probability", NULL
,
3296 RMAP_EVENT_MATCH_DELETED
);
3297 return bgp_route_match_delete (vty
, "probability", argv
[idx_number
]->arg
,
3298 RMAP_EVENT_MATCH_DELETED
);
3302 DEFUN (match_ip_route_source
,
3303 match_ip_route_source_cmd
,
3304 "match ip route-source <(1-199)|(1300-2699)|WORD>",
3307 "Match advertising source address of route\n"
3308 "IP access-list number\n"
3309 "IP access-list number (expanded range)\n"
3310 "IP standard access-list name\n")
3313 return bgp_route_match_add (vty
, "ip route-source", argv
[idx_acl
]->arg
,
3314 RMAP_EVENT_FILTER_ADDED
);
3318 DEFUN (no_match_ip_route_source
,
3319 no_match_ip_route_source_cmd
,
3320 "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
3324 "Match advertising source address of route\n"
3325 "IP access-list number\n"
3326 "IP access-list number (expanded range)\n"
3327 "IP standard access-list name\n")
3330 if (argc
<= idx_number
)
3331 return bgp_route_match_delete (vty
, "ip route-source",
3332 NULL
, RMAP_EVENT_FILTER_DELETED
);
3333 return bgp_route_match_delete (vty
, "ip route-source",
3334 argv
[idx_number
]->arg
, RMAP_EVENT_FILTER_DELETED
);
3338 DEFUN (match_ip_route_source_prefix_list
,
3339 match_ip_route_source_prefix_list_cmd
,
3340 "match ip route-source prefix-list WORD",
3343 "Match advertising source address of route\n"
3344 "Match entries of prefix-lists\n"
3345 "IP prefix-list name\n")
3348 return bgp_route_match_add (vty
, "ip route-source prefix-list",
3349 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3353 DEFUN (no_match_ip_route_source_prefix_list
,
3354 no_match_ip_route_source_prefix_list_cmd
,
3355 "no match ip route-source prefix-list [WORD]",
3359 "Match advertising source address of route\n"
3360 "Match entries of prefix-lists\n"
3361 "IP prefix-list name\n")
3364 if (argc
<= idx_word
)
3365 return bgp_route_match_delete (vty
, "ip route-source prefix-list",
3366 NULL
, RMAP_EVENT_PLIST_DELETED
);
3367 return bgp_route_match_delete (vty
, "ip route-source prefix-list",
3368 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_DELETED
);
3372 DEFUN (match_local_pref
,
3373 match_local_pref_cmd
,
3374 "match local-preference (0-4294967295)",
3376 "Match local-preference of route\n"
3380 return bgp_route_match_add (vty
, "local-preference", argv
[idx_number
]->arg
,
3381 RMAP_EVENT_MATCH_ADDED
);
3385 DEFUN (no_match_local_pref
,
3386 no_match_local_pref_cmd
,
3387 "no match local-preference [(0-4294967295)]",
3390 "Match local preference of route\n"
3391 "Local preference value\n")
3393 int idx_localpref
= 3;
3394 if (argc
<= idx_localpref
)
3395 return bgp_route_match_delete (vty
, "local-preference",
3396 NULL
, RMAP_EVENT_MATCH_DELETED
);
3397 return bgp_route_match_delete (vty
, "local-preference",
3398 argv
[idx_localpref
]->arg
,
3399 RMAP_EVENT_MATCH_DELETED
);
3403 DEFUN (match_community
,
3404 match_community_cmd
,
3405 "match community <(1-99)|(100-500)|WORD> [exact-match]",
3407 "Match BGP community list\n"
3408 "Community-list number (standard)\n"
3409 "Community-list number (expanded)\n"
3410 "Community-list name\n"
3411 "Do exact matching of communities\n")
3413 int idx_comm_list
= 2;
3419 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3420 strlen (argv
[idx_comm_list
]->arg
) +
3421 strlen ("exact-match") + 2);
3423 sprintf (argstr
, "%s exact-match", argv
[idx_comm_list
]->arg
);
3426 argstr
= argv
[idx_comm_list
]->arg
;
3428 ret
= bgp_route_match_add (vty
, "community", argstr
,
3429 RMAP_EVENT_CLIST_ADDED
);
3431 if (argstr
!= argv
[idx_comm_list
]->arg
)
3432 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3437 DEFUN (no_match_community
,
3438 no_match_community_cmd
,
3439 "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
3442 "Match BGP community list\n"
3443 "Community-list number (standard)\n"
3444 "Community-list number (expanded)\n"
3445 "Community-list name\n"
3446 "Do exact matching of communities\n")
3448 return bgp_route_match_delete (vty
, "community", NULL
,
3449 RMAP_EVENT_CLIST_DELETED
);
3452 DEFUN (match_lcommunity
,
3453 match_lcommunity_cmd
,
3454 "match large-community <(1-99)|(100-500)|WORD>",
3456 "Match BGP large community list\n"
3457 "Large Community-list number (standard)\n"
3458 "Large Community-list number (expanded)\n"
3459 "Large Community-list name\n")
3461 return bgp_route_match_add (vty
, "large-community", argv
[2]->arg
,
3462 RMAP_EVENT_LLIST_ADDED
);
3465 DEFUN (no_match_lcommunity
,
3466 no_match_lcommunity_cmd
,
3467 "no match large-community [<(1-99)|(100-500)|WORD>]",
3470 "Match BGP large community list\n"
3471 "Large Community-list number (standard)\n"
3472 "Large Community-list number (expanded)\n"
3473 "Large Community-list name\n")
3475 return bgp_route_match_delete (vty
, "large-community", NULL
,
3476 RMAP_EVENT_LLIST_DELETED
);
3479 DEFUN (match_ecommunity
,
3480 match_ecommunity_cmd
,
3481 "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")
3488 int idx_comm_list
= 2;
3489 return bgp_route_match_add (vty
, "extcommunity", argv
[idx_comm_list
]->arg
,
3490 RMAP_EVENT_ECLIST_ADDED
);
3494 DEFUN (no_match_ecommunity
,
3495 no_match_ecommunity_cmd
,
3496 "no match extcommunity [<(1-99)|(100-500)|WORD>]",
3499 "Match BGP/VPN extended community list\n"
3500 "Extended community-list number (standard)\n"
3501 "Extended community-list number (expanded)\n"
3502 "Extended community-list name\n")
3504 return bgp_route_match_delete (vty
, "extcommunity", NULL
,
3505 RMAP_EVENT_ECLIST_DELETED
);
3509 DEFUN (match_aspath
,
3511 "match as-path WORD",
3513 "Match BGP AS path list\n"
3514 "AS path access-list name\n")
3517 return bgp_route_match_add (vty
, "as-path", argv
[idx_word
]->arg
,
3518 RMAP_EVENT_ASLIST_ADDED
);
3522 DEFUN (no_match_aspath
,
3523 no_match_aspath_cmd
,
3524 "no match as-path [WORD]",
3527 "Match BGP AS path list\n"
3528 "AS path access-list name\n")
3530 return bgp_route_match_delete (vty
, "as-path", NULL
,
3531 RMAP_EVENT_ASLIST_DELETED
);
3535 DEFUN (match_origin
,
3537 "match origin <egp|igp|incomplete>",
3542 "unknown heritage\n")
3545 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
3546 return bgp_route_match_add (vty
, "origin", "igp",
3547 RMAP_EVENT_MATCH_ADDED
);
3548 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
3549 return bgp_route_match_add (vty
, "origin", "egp",
3550 RMAP_EVENT_MATCH_ADDED
);
3551 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3552 return bgp_route_match_add (vty
, "origin", "incomplete",
3553 RMAP_EVENT_MATCH_ADDED
);
3559 DEFUN (no_match_origin
,
3560 no_match_origin_cmd
,
3561 "no match origin [<egp|igp|incomplete>]",
3567 "unknown heritage\n")
3569 return bgp_route_match_delete (vty
, "origin", NULL
,
3570 RMAP_EVENT_MATCH_DELETED
);
3573 DEFUN (set_ip_nexthop_peer
,
3574 set_ip_nexthop_peer_cmd
,
3575 "set ip next-hop peer-address",
3578 "Next hop address\n"
3579 "Use peer address (for BGP only)\n")
3581 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3582 "ip next-hop", "peer-address");
3585 DEFUN (set_ip_nexthop_unchanged
,
3586 set_ip_nexthop_unchanged_cmd
,
3587 "set ip next-hop unchanged",
3590 "Next hop address\n"
3591 "Don't modify existing Next hop address\n")
3593 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3594 "ip next-hop", "unchanged");
3598 DEFUN (set_local_pref
,
3600 "set local-preference (0-4294967295)",
3602 "BGP local preference path attribute\n"
3603 "Preference value\n")
3606 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3607 "local-preference", argv
[idx_number
]->arg
);
3611 DEFUN (no_set_local_pref
,
3612 no_set_local_pref_cmd
,
3613 "no set local-preference [(0-4294967295)]",
3616 "BGP local preference path attribute\n"
3617 "Preference value\n")
3619 int idx_localpref
= 3;
3620 if (argc
<= idx_localpref
)
3621 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3622 "local-preference", NULL
);
3623 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3624 "local-preference", argv
[idx_localpref
]->arg
);
3630 "set weight (0-4294967295)",
3632 "BGP weight for routing table\n"
3636 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "weight",
3637 argv
[idx_number
]->arg
);
3641 DEFUN (no_set_weight
,
3643 "no set weight [(0-4294967295)]",
3646 "BGP weight for routing table\n"
3650 if (argc
<= idx_weight
)
3651 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3653 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
), "weight",
3654 argv
[idx_weight
]->arg
);
3658 DEFUN (set_aspath_prepend_asn
,
3659 set_aspath_prepend_asn_cmd
,
3660 "set as-path prepend (1-4294967295)...",
3662 "Transform BGP AS_PATH attribute\n"
3663 "Prepend to the as-path\n"
3670 str
= argv_concat (argv
, argc
, idx_asn
);
3671 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3672 "as-path prepend", str
);
3673 XFREE (MTYPE_TMP
, str
);
3678 DEFUN (set_aspath_prepend_lastas
,
3679 set_aspath_prepend_lastas_cmd
,
3680 "set as-path prepend last-as (1-10)",
3682 "Transform BGP AS_PATH attribute\n"
3683 "Prepend to the as-path\n"
3684 "Use the peer's AS-number\n"
3685 "Number of times to insert\n")
3687 return set_aspath_prepend_asn (self
, vty
, argc
, argv
);
3690 DEFUN (no_set_aspath_prepend
,
3691 no_set_aspath_prepend_cmd
,
3692 "no set as-path prepend [(1-4294967295)]",
3695 "Transform BGP AS_PATH attribute\n"
3696 "Prepend to the as-path\n"
3703 str
= argv_concat (argv
, argc
, idx_asn
);
3704 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3705 "as-path prepend", str
);
3706 XFREE (MTYPE_TMP
, str
);
3711 DEFUN (set_aspath_exclude
,
3712 set_aspath_exclude_cmd
,
3713 "set as-path exclude (1-4294967295)...",
3715 "Transform BGP AS-path attribute\n"
3716 "Exclude from the as-path\n"
3723 str
= argv_concat (argv
, argc
, idx_asn
);
3724 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3725 "as-path exclude", str
);
3726 XFREE (MTYPE_TMP
, str
);
3730 DEFUN (no_set_aspath_exclude
,
3731 no_set_aspath_exclude_cmd
,
3732 "no set as-path exclude (1-4294967295)...",
3735 "Transform BGP AS_PATH attribute\n"
3736 "Exclude from the as-path\n"
3743 str
= argv_concat (argv
, argc
, idx_asn
);
3744 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3745 "as-path exclude", str
);
3746 XFREE (MTYPE_TMP
, str
);
3751 DEFUN (set_community
,
3753 "set community AA:NN...",
3755 "BGP community attribute\n"
3763 struct community
*com
= NULL
;
3768 b
= buffer_new (1024);
3770 for (i
= idx_aa_nn
; i
< argc
; i
++)
3772 if (strncmp (argv
[i
]->arg
, "additive", strlen (argv
[i
]->arg
)) == 0)
3779 buffer_putc (b
, ' ');
3783 if (strncmp (argv
[i
]->arg
, "internet", strlen (argv
[i
]->arg
)) == 0)
3785 buffer_putstr (b
, "internet");
3788 if (strncmp (argv
[i
]->arg
, "local-AS", strlen (argv
[i
]->arg
)) == 0)
3790 buffer_putstr (b
, "local-AS");
3793 if (strncmp (argv
[i
]->arg
, "no-a", strlen ("no-a")) == 0
3794 && strncmp (argv
[i
]->arg
, "no-advertise", strlen (argv
[i
]->arg
)) == 0)
3796 buffer_putstr (b
, "no-advertise");
3799 if (strncmp (argv
[i
]->arg
, "no-e", strlen ("no-e"))== 0
3800 && strncmp (argv
[i
]->arg
, "no-export", strlen (argv
[i
]->arg
)) == 0)
3802 buffer_putstr (b
, "no-export");
3805 buffer_putstr (b
, argv
[i
]->arg
);
3807 buffer_putc (b
, '\0');
3809 /* Fetch result string then compile it to communities attribute. */
3810 str
= buffer_getstr (b
);
3815 com
= community_str2com (str
);
3816 XFREE (MTYPE_TMP
, str
);
3819 /* Can't compile user input into communities attribute. */
3822 vty_out (vty
, "%% Malformed communities attribute%s", VTY_NEWLINE
);
3826 /* Set communites attribute string. */
3827 str
= community_str (com
);
3831 argstr
= XCALLOC (MTYPE_TMP
, strlen (str
) + strlen (" additive") + 1);
3832 strcpy (argstr
, str
);
3833 strcpy (argstr
+ strlen (str
), " additive");
3834 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3835 "community", argstr
);
3836 XFREE (MTYPE_TMP
, argstr
);
3839 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3842 community_free (com
);
3847 DEFUN (set_community_none
,
3848 set_community_none_cmd
,
3849 "set community none",
3851 "BGP community attribute\n"
3852 "No community attribute\n")
3854 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "community",
3858 DEFUN (no_set_community
,
3859 no_set_community_cmd
,
3860 "no set community AA:NN...",
3863 "BGP community attribute\n"
3866 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3872 DEFUN (set_community_delete
,
3873 set_community_delete_cmd
,
3874 "set comm-list <(1-99)|(100-500)|WORD> delete",
3876 "set BGP community list (for deletion)\n"
3877 "Community-list number (standard)\n"
3878 "Community-list number (expanded)\n"
3879 "Community-list name\n"
3880 "Delete matching communities\n")
3882 int idx_comm_list
= 2;
3885 str
= XCALLOC (MTYPE_TMP
, strlen (argv
[idx_comm_list
]->arg
) + strlen (" delete") + 1);
3886 strcpy (str
, argv
[idx_comm_list
]->arg
);
3887 strcpy (str
+ strlen (argv
[idx_comm_list
]->arg
), " delete");
3889 generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "comm-list", str
);
3891 XFREE (MTYPE_TMP
, str
);
3895 DEFUN (no_set_community_delete
,
3896 no_set_community_delete_cmd
,
3897 "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
3900 "set BGP community list (for deletion)\n"
3901 "Community-list number (standard)\n"
3902 "Community-list number (expanded)\n"
3903 "Community-list name\n"
3904 "Delete matching communities\n")
3906 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3910 DEFUN (set_lcommunity
,
3912 "set large-community AA:BB:CC...",
3914 "BGP large community attribute\n"
3915 "Large Community number in aa:bb:cc format or additive\n")
3920 str
= argv_concat (argv
, argc
, 2);
3921 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "large-community", str
);
3922 XFREE (MTYPE_TMP
, str
);
3927 DEFUN (set_lcommunity_none
,
3928 set_lcommunity_none_cmd
,
3929 "set large-community none",
3931 "BGP large community attribute\n"
3932 "No large community attribute\n")
3934 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3935 "large-community", "none");
3938 DEFUN (no_set_lcommunity
,
3939 no_set_lcommunity_cmd
,
3940 "no set large-community none",
3943 "BGP large community attribute\n"
3944 "No community attribute\n")
3946 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3947 "large-community", NULL
);
3950 DEFUN (no_set_lcommunity1
,
3951 no_set_lcommunity1_cmd
,
3952 "no set large-community AA:BB:CC...",
3955 "BGP large community attribute\n"
3956 "Large community in AA:BB:CC... format or additive\n")
3958 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3959 "large-community", NULL
);
3962 DEFUN (set_lcommunity_delete
,
3963 set_lcommunity_delete_cmd
,
3964 "set large-comm-list <(1-99)|(100-500)|WORD> delete",
3966 "set BGP large community list (for deletion)\n"
3967 "Large Community-list number (standard)\n"
3968 "Large Communitly-list number (expanded)\n"
3969 "Large Community-list name\n"
3970 "Delete matching large communities\n")
3974 str
= XCALLOC (MTYPE_TMP
, strlen (argv
[2]->arg
) + strlen (" delete") + 1);
3975 strcpy (str
, argv
[2]->arg
);
3976 strcpy (str
+ strlen (argv
[2]->arg
), " delete");
3978 generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3979 "large-comm-list", str
);
3981 XFREE (MTYPE_TMP
, str
);
3985 DEFUN (no_set_lcommunity_delete
,
3986 no_set_lcommunity_delete_cmd
,
3987 "no set large-comm-list <(1-99)|(100-500)|WORD> [delete]",
3990 "set BGP large community list (for deletion)\n"
3991 "Large Community-list number (standard)\n"
3992 "Large Communitly-list number (expanded)\n"
3993 "Large Community-list name\n"
3994 "Delete matching large communities\n")
3996 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3997 "large-comm-list", NULL
);
4000 DEFUN (set_ecommunity_rt
,
4001 set_ecommunity_rt_cmd
,
4002 "set extcommunity rt ASN:nn_or_IP-address:nn...",
4004 "BGP extended community attribute\n"
4005 "Route Target extended community\n"
4006 "VPN extended community\n")
4012 str
= argv_concat (argv
, argc
, idx_asn_nn
);
4013 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4014 "extcommunity rt", str
);
4015 XFREE (MTYPE_TMP
, str
);
4020 DEFUN (no_set_ecommunity_rt
,
4021 no_set_ecommunity_rt_cmd
,
4022 "no set extcommunity rt ASN:nn_or_IP-address:nn...",
4025 "BGP extended community attribute\n"
4026 "Route Target extended community\n"
4027 "VPN extended community\n")
4029 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4030 "extcommunity rt", NULL
);
4034 DEFUN (set_ecommunity_soo
,
4035 set_ecommunity_soo_cmd
,
4036 "set extcommunity soo ASN:nn_or_IP-address:nn...",
4038 "BGP extended community attribute\n"
4039 "Site-of-Origin extended community\n"
4040 "VPN extended community\n")
4046 str
= argv_concat (argv
, argc
, idx_asn_nn
);
4047 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4048 "extcommunity soo", str
);
4049 XFREE (MTYPE_TMP
, str
);
4054 DEFUN (no_set_ecommunity_soo
,
4055 no_set_ecommunity_soo_cmd
,
4056 "no set extcommunity soo ASN:nn_or_IP-address:nn...",
4059 "BGP extended community attribute\n"
4060 "Site-of-Origin extended community\n"
4061 "VPN extended community\n")
4063 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4064 "extcommunity soo", NULL
);
4070 "set origin <egp|igp|incomplete>",
4075 "unknown heritage\n")
4078 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
4079 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4081 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
4082 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4084 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
4085 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4092 DEFUN (no_set_origin
,
4094 "no set origin [<egp|igp|incomplete>]",
4100 "unknown heritage\n")
4102 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4107 DEFUN (set_atomic_aggregate
,
4108 set_atomic_aggregate_cmd
,
4109 "set atomic-aggregate",
4111 "BGP atomic aggregate attribute\n" )
4113 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4114 "atomic-aggregate", NULL
);
4117 DEFUN (no_set_atomic_aggregate
,
4118 no_set_atomic_aggregate_cmd
,
4119 "no set atomic-aggregate",
4122 "BGP atomic aggregate attribute\n" )
4124 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4125 "atomic-aggregate", NULL
);
4128 DEFUN (set_aggregator_as
,
4129 set_aggregator_as_cmd
,
4130 "set aggregator as (1-4294967295) A.B.C.D",
4132 "BGP aggregator attribute\n"
4133 "AS number of aggregator\n"
4135 "IP address of aggregator\n")
4140 struct in_addr address
;
4143 ret
= inet_aton (argv
[idx_ipv4
]->arg
, &address
);
4146 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
4150 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
4151 strlen (argv
[idx_number
]->arg
) + strlen (argv
[idx_ipv4
]->arg
) + 2);
4153 sprintf (argstr
, "%s %s", argv
[idx_number
]->arg
, argv
[idx_ipv4
]->arg
);
4155 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4156 "aggregator as", argstr
);
4158 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4164 DEFUN (no_set_aggregator_as
,
4165 no_set_aggregator_as_cmd
,
4166 "no set aggregator as [(1-4294967295) A.B.C.D]",
4169 "BGP aggregator attribute\n"
4170 "AS number of aggregator\n"
4172 "IP address of aggregator\n")
4177 struct in_addr address
;
4180 if (argc
<= idx_asn
)
4181 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4182 "aggregator as", NULL
);
4184 ret
= inet_aton (argv
[idx_ip
]->arg
, &address
);
4187 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
4191 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
4192 strlen (argv
[idx_asn
]->arg
) + strlen (argv
[idx_ip
]->arg
) + 2);
4194 sprintf (argstr
, "%s %s", argv
[idx_asn
]->arg
, argv
[idx_ip
]->arg
);
4196 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4197 "aggregator as", argstr
);
4199 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4204 DEFUN (match_ipv6_next_hop
,
4205 match_ipv6_next_hop_cmd
,
4206 "match ipv6 next-hop X:X::X:X",
4209 "Match IPv6 next-hop address of route\n"
4210 "IPv6 address of next hop\n")
4213 return bgp_route_match_add (vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4214 RMAP_EVENT_MATCH_ADDED
);
4217 DEFUN (no_match_ipv6_next_hop
,
4218 no_match_ipv6_next_hop_cmd
,
4219 "no match ipv6 next-hop X:X::X:X",
4223 "Match IPv6 next-hop address of route\n"
4224 "IPv6 address of next hop\n")
4227 return bgp_route_match_delete (vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4228 RMAP_EVENT_MATCH_DELETED
);
4232 DEFUN (set_ipv6_nexthop_peer
,
4233 set_ipv6_nexthop_peer_cmd
,
4234 "set ipv6 next-hop peer-address",
4237 "Next hop address\n"
4238 "Use peer address (for BGP only)\n")
4240 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4241 "ipv6 next-hop peer-address", NULL
);
4244 DEFUN (no_set_ipv6_nexthop_peer
,
4245 no_set_ipv6_nexthop_peer_cmd
,
4246 "no set ipv6 next-hop peer-address",
4250 "IPv6 next-hop address\n"
4251 "Use peer address (for BGP only)\n")
4253 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4254 "ipv6 next-hop peer-address", NULL
);
4257 DEFUN (set_ipv6_nexthop_prefer_global
,
4258 set_ipv6_nexthop_prefer_global_cmd
,
4259 "set ipv6 next-hop prefer-global",
4262 "IPv6 next-hop address\n"
4263 "Prefer global over link-local if both exist\n")
4265 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4266 "ipv6 next-hop prefer-global", NULL
);;
4269 DEFUN (no_set_ipv6_nexthop_prefer_global
,
4270 no_set_ipv6_nexthop_prefer_global_cmd
,
4271 "no set ipv6 next-hop prefer-global",
4275 "IPv6 next-hop address\n"
4276 "Prefer global over link-local if both exist\n")
4278 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4279 "ipv6 next-hop prefer-global", NULL
);
4282 DEFUN (set_ipv6_nexthop_global
,
4283 set_ipv6_nexthop_global_cmd
,
4284 "set ipv6 next-hop global X:X::X:X",
4287 "IPv6 next-hop address\n"
4288 "IPv6 global address\n"
4289 "IPv6 address of next hop\n")
4292 struct in6_addr addr
;
4295 ret
= inet_pton (AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
4298 vty_out (vty
, "%% Malformed nexthop address%s", VTY_NEWLINE
);
4301 if (IN6_IS_ADDR_UNSPECIFIED(&addr
) ||
4302 IN6_IS_ADDR_LOOPBACK(&addr
) ||
4303 IN6_IS_ADDR_MULTICAST(&addr
) ||
4304 IN6_IS_ADDR_LINKLOCAL(&addr
))
4306 vty_out (vty
, "%% Invalid global nexthop address%s", VTY_NEWLINE
);
4310 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4311 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4315 DEFUN (no_set_ipv6_nexthop_global
,
4316 no_set_ipv6_nexthop_global_cmd
,
4317 "no set ipv6 next-hop global X:X::X:X",
4321 "IPv6 next-hop address\n"
4322 "IPv6 global address\n"
4323 "IPv6 address of next hop\n")
4326 if (argc
<= idx_ipv6
)
4327 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4328 "ipv6 next-hop global", NULL
);
4329 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4330 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4333 #ifdef KEEP_OLD_VPN_COMMANDS
4334 DEFUN (set_vpn_nexthop
,
4335 set_vpn_nexthop_cmd
,
4336 "set <vpnv4|vpnv6> next-hop <A.B.C.D|X:X::X:X>",
4338 "VPNv4 information\n"
4339 "VPNv6 information\n"
4340 "VPN next-hop address\n"
4341 "IP address of next hop\n"
4342 "IPv6 address of next hop\n")
4348 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
4351 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4352 "ip vpn next-hop", argv
[idx_ip
]->arg
);
4354 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4355 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4360 DEFUN (no_set_vpn_nexthop
,
4361 no_set_vpn_nexthop_cmd
,
4362 "no set vpn next-hop <A.B.C.D|X:X::X:X>",
4366 "VPN next-hop address\n"
4367 "IP address of next hop\n"
4368 "IPv6 address of next hop\n")
4378 arg
= argv
[idx_ip
]->arg
;
4379 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
4382 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4383 "ip vpn next-hop", arg
);
4385 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4386 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4390 #endif /* KEEP_OLD_VPN_COMMANDS */
4392 DEFUN (set_ipx_vpn_nexthop
,
4393 set_ipx_vpn_nexthop_cmd
,
4394 "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
4396 "IPv4 information\n"
4397 "IPv6 information\n"
4399 "VPN next-hop address\n"
4400 "IP address of next hop\n"
4401 "IPv6 address of next hop\n")
4407 if (argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
))
4410 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4411 "ip vpn next-hop", argv
[idx_ip
]->arg
);
4413 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4414 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4419 DEFUN (no_set_ipx_vpn_nexthop
,
4420 no_set_ipx_vpn_nexthop_cmd
,
4421 "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
4424 "IPv4 information\n"
4425 "IPv6 information\n"
4427 "VPN next-hop address\n"
4428 "IP address of next hop\n"
4429 "IPv6 address of next hop\n")
4439 arg
= argv
[idx_ip
]->arg
;
4440 if (argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
))
4443 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4444 "ip vpn next-hop", arg
);
4446 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4447 "ipv6 vpn next-hop", arg
);
4452 DEFUN (set_originator_id
,
4453 set_originator_id_cmd
,
4454 "set originator-id A.B.C.D",
4456 "BGP originator ID attribute\n"
4457 "IP address of originator\n")
4460 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4461 "originator-id", argv
[idx_ipv4
]->arg
);
4465 DEFUN (no_set_originator_id
,
4466 no_set_originator_id_cmd
,
4467 "no set originator-id [A.B.C.D]",
4470 "BGP originator ID attribute\n"
4471 "IP address of originator\n")
4474 char *arg
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
4476 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4477 "originator-id", arg
);
4481 /* Initialization of route map. */
4483 bgp_route_map_init (void)
4487 route_map_add_hook (bgp_route_map_add
);
4488 route_map_delete_hook (bgp_route_map_delete
);
4489 route_map_event_hook (bgp_route_map_event
);
4491 route_map_match_interface_hook (generic_match_add
);
4492 route_map_no_match_interface_hook (generic_match_delete
);
4494 route_map_match_ip_address_hook (generic_match_add
);
4495 route_map_no_match_ip_address_hook (generic_match_delete
);
4497 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
4498 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
4500 route_map_match_ip_next_hop_hook (generic_match_add
);
4501 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
4503 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
4504 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
4506 route_map_match_ipv6_address_hook (generic_match_add
);
4507 route_map_no_match_ipv6_address_hook (generic_match_delete
);
4509 route_map_match_ipv6_address_prefix_list_hook (generic_match_add
);
4510 route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete
);
4512 route_map_match_metric_hook (generic_match_add
);
4513 route_map_no_match_metric_hook (generic_match_delete
);
4515 route_map_match_tag_hook (generic_match_add
);
4516 route_map_no_match_tag_hook (generic_match_delete
);
4518 route_map_set_ip_nexthop_hook (generic_set_add
);
4519 route_map_no_set_ip_nexthop_hook (generic_set_delete
);
4521 route_map_set_ipv6_nexthop_local_hook (generic_set_add
);
4522 route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete
);
4524 route_map_set_metric_hook (generic_set_add
);
4525 route_map_no_set_metric_hook (generic_set_delete
);
4527 route_map_set_tag_hook (generic_set_add
);
4528 route_map_no_set_tag_hook (generic_set_delete
);
4530 route_map_install_match (&route_match_peer_cmd
);
4531 route_map_install_match (&route_match_local_pref_cmd
);
4532 route_map_install_match (&route_match_ip_address_cmd
);
4533 route_map_install_match (&route_match_ip_next_hop_cmd
);
4534 route_map_install_match (&route_match_ip_route_source_cmd
);
4535 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
4536 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
4537 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd
);
4538 route_map_install_match (&route_match_aspath_cmd
);
4539 route_map_install_match (&route_match_community_cmd
);
4540 route_map_install_match (&route_match_lcommunity_cmd
);
4541 route_map_install_match (&route_match_ecommunity_cmd
);
4542 route_map_install_match (&route_match_local_pref_cmd
);
4543 route_map_install_match (&route_match_metric_cmd
);
4544 route_map_install_match (&route_match_origin_cmd
);
4545 route_map_install_match (&route_match_probability_cmd
);
4546 route_map_install_match (&route_match_interface_cmd
);
4547 route_map_install_match (&route_match_tag_cmd
);
4549 route_map_install_set (&route_set_ip_nexthop_cmd
);
4550 route_map_install_set (&route_set_local_pref_cmd
);
4551 route_map_install_set (&route_set_weight_cmd
);
4552 route_map_install_set (&route_set_metric_cmd
);
4553 route_map_install_set (&route_set_aspath_prepend_cmd
);
4554 route_map_install_set (&route_set_aspath_exclude_cmd
);
4555 route_map_install_set (&route_set_origin_cmd
);
4556 route_map_install_set (&route_set_atomic_aggregate_cmd
);
4557 route_map_install_set (&route_set_aggregator_as_cmd
);
4558 route_map_install_set (&route_set_community_cmd
);
4559 route_map_install_set (&route_set_community_delete_cmd
);
4560 route_map_install_set (&route_set_lcommunity_cmd
);
4561 route_map_install_set (&route_set_lcommunity_delete_cmd
);
4562 route_map_install_set (&route_set_vpnv4_nexthop_cmd
);
4563 route_map_install_set (&route_set_vpnv6_nexthop_cmd
);
4564 route_map_install_set (&route_set_originator_id_cmd
);
4565 route_map_install_set (&route_set_ecommunity_rt_cmd
);
4566 route_map_install_set (&route_set_ecommunity_soo_cmd
);
4567 route_map_install_set (&route_set_tag_cmd
);
4569 install_element (RMAP_NODE
, &match_peer_cmd
);
4570 install_element (RMAP_NODE
, &match_peer_local_cmd
);
4571 install_element (RMAP_NODE
, &no_match_peer_cmd
);
4572 install_element (RMAP_NODE
, &match_ip_route_source_cmd
);
4573 install_element (RMAP_NODE
, &no_match_ip_route_source_cmd
);
4574 install_element (RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
4575 install_element (RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
4577 install_element (RMAP_NODE
, &match_aspath_cmd
);
4578 install_element (RMAP_NODE
, &no_match_aspath_cmd
);
4579 install_element (RMAP_NODE
, &match_local_pref_cmd
);
4580 install_element (RMAP_NODE
, &no_match_local_pref_cmd
);
4581 install_element (RMAP_NODE
, &match_community_cmd
);
4582 install_element (RMAP_NODE
, &no_match_community_cmd
);
4583 install_element (RMAP_NODE
, &match_lcommunity_cmd
);
4584 install_element (RMAP_NODE
, &no_match_lcommunity_cmd
);
4585 install_element (RMAP_NODE
, &match_ecommunity_cmd
);
4586 install_element (RMAP_NODE
, &no_match_ecommunity_cmd
);
4587 install_element (RMAP_NODE
, &match_origin_cmd
);
4588 install_element (RMAP_NODE
, &no_match_origin_cmd
);
4589 install_element (RMAP_NODE
, &match_probability_cmd
);
4590 install_element (RMAP_NODE
, &no_match_probability_cmd
);
4592 install_element (RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
4593 install_element (RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
4594 install_element (RMAP_NODE
, &set_local_pref_cmd
);
4595 install_element (RMAP_NODE
, &no_set_local_pref_cmd
);
4596 install_element (RMAP_NODE
, &set_weight_cmd
);
4597 install_element (RMAP_NODE
, &no_set_weight_cmd
);
4598 install_element (RMAP_NODE
, &set_aspath_prepend_asn_cmd
);
4599 install_element (RMAP_NODE
, &set_aspath_prepend_lastas_cmd
);
4600 install_element (RMAP_NODE
, &set_aspath_exclude_cmd
);
4601 install_element (RMAP_NODE
, &no_set_aspath_prepend_cmd
);
4602 install_element (RMAP_NODE
, &no_set_aspath_exclude_cmd
);
4603 install_element (RMAP_NODE
, &set_origin_cmd
);
4604 install_element (RMAP_NODE
, &no_set_origin_cmd
);
4605 install_element (RMAP_NODE
, &set_atomic_aggregate_cmd
);
4606 install_element (RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
4607 install_element (RMAP_NODE
, &set_aggregator_as_cmd
);
4608 install_element (RMAP_NODE
, &no_set_aggregator_as_cmd
);
4609 install_element (RMAP_NODE
, &set_community_cmd
);
4610 install_element (RMAP_NODE
, &set_community_none_cmd
);
4611 install_element (RMAP_NODE
, &no_set_community_cmd
);
4612 install_element (RMAP_NODE
, &set_community_delete_cmd
);
4613 install_element (RMAP_NODE
, &no_set_community_delete_cmd
);
4614 install_element (RMAP_NODE
, &set_lcommunity_cmd
);
4615 install_element (RMAP_NODE
, &set_lcommunity_none_cmd
);
4616 install_element (RMAP_NODE
, &no_set_lcommunity_cmd
);
4617 install_element (RMAP_NODE
, &no_set_lcommunity1_cmd
);
4618 install_element (RMAP_NODE
, &set_lcommunity_delete_cmd
);
4619 install_element (RMAP_NODE
, &no_set_lcommunity_delete_cmd
);
4620 install_element (RMAP_NODE
, &set_ecommunity_rt_cmd
);
4621 install_element (RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
4622 install_element (RMAP_NODE
, &set_ecommunity_soo_cmd
);
4623 install_element (RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
4624 #ifdef KEEP_OLD_VPN_COMMANDS
4625 install_element (RMAP_NODE
, &set_vpn_nexthop_cmd
);
4626 install_element (RMAP_NODE
, &no_set_vpn_nexthop_cmd
);
4627 #endif /* KEEP_OLD_VPN_COMMANDS */
4628 install_element (RMAP_NODE
, &set_ipx_vpn_nexthop_cmd
);
4629 install_element (RMAP_NODE
, &no_set_ipx_vpn_nexthop_cmd
);
4630 install_element (RMAP_NODE
, &set_originator_id_cmd
);
4631 install_element (RMAP_NODE
, &no_set_originator_id_cmd
);
4633 route_map_install_match (&route_match_ipv6_address_cmd
);
4634 route_map_install_match (&route_match_ipv6_next_hop_cmd
);
4635 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd
);
4636 route_map_install_set (&route_set_ipv6_nexthop_global_cmd
);
4637 route_map_install_set (&route_set_ipv6_nexthop_prefer_global_cmd
);
4638 route_map_install_set (&route_set_ipv6_nexthop_local_cmd
);
4639 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd
);
4641 install_element (RMAP_NODE
, &match_ipv6_next_hop_cmd
);
4642 install_element (RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
4643 install_element (RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
4644 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
4645 install_element (RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
4646 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
4647 install_element (RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
4648 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
4652 bgp_route_map_terminate (void)
4654 /* ToDo: Cleanup all the used memory */
4656 route_map_add_hook (NULL
);
4657 route_map_delete_hook (NULL
);
4658 route_map_event_hook (NULL
);