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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
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 (lcommunity_list_match (bgp_info
->attr
->lcommunity
, list
))
878 /* Compile function for community match. */
880 route_match_lcommunity_compile (const char *arg
)
882 struct rmap_community
*rcom
;
886 rcom
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_community
));
888 p
= strchr (arg
, ' ');
892 rcom
->name
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
893 memcpy (rcom
->name
, arg
, len
);
897 rcom
->name
= XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
903 /* Compile function for community match. */
905 route_match_lcommunity_free (void *rule
)
907 struct rmap_community
*rcom
= rule
;
909 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
910 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
);
913 /* Route map commands for community matching. */
914 struct route_map_rule_cmd route_match_lcommunity_cmd
=
917 route_match_lcommunity
,
918 route_match_lcommunity_compile
,
919 route_match_lcommunity_free
923 /* Match function for extcommunity match. */
924 static route_map_result_t
925 route_match_ecommunity (void *rule
, struct prefix
*prefix
,
926 route_map_object_t type
, void *object
)
928 struct community_list
*list
;
929 struct bgp_info
*bgp_info
;
931 if (type
== RMAP_BGP
)
935 list
= community_list_lookup (bgp_clist
, (char *) rule
,
936 EXTCOMMUNITY_LIST_MASTER
);
940 if (ecommunity_list_match (bgp_info
->attr
->ecommunity
, list
))
946 /* Compile function for extcommunity match. */
948 route_match_ecommunity_compile (const char *arg
)
950 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
953 /* Compile function for extcommunity match. */
955 route_match_ecommunity_free (void *rule
)
957 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
960 /* Route map commands for community matching. */
961 struct route_map_rule_cmd route_match_ecommunity_cmd
=
964 route_match_ecommunity
,
965 route_match_ecommunity_compile
,
966 route_match_ecommunity_free
969 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
970 and `address-family vpnv4'. */
973 static route_map_result_t
974 route_match_origin (void *rule
, struct prefix
*prefix
,
975 route_map_object_t type
, void *object
)
978 struct bgp_info
*bgp_info
;
980 if (type
== RMAP_BGP
)
985 if (bgp_info
->attr
->origin
== *origin
)
993 route_match_origin_compile (const char *arg
)
997 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
999 if (strcmp (arg
, "igp") == 0)
1001 else if (strcmp (arg
, "egp") == 0)
1009 /* Free route map's compiled `ip address' value. */
1011 route_match_origin_free (void *rule
)
1013 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1016 /* Route map commands for origin matching. */
1017 struct route_map_rule_cmd route_match_origin_cmd
=
1021 route_match_origin_compile
,
1022 route_match_origin_free
1025 /* match probability { */
1027 static route_map_result_t
1028 route_match_probability (void *rule
, struct prefix
*prefix
,
1029 route_map_object_t type
, void *object
)
1033 switch (*(long *) rule
)
1036 case RAND_MAX
: return RMAP_MATCH
;
1038 if (r
< *(long *) rule
)
1044 return RMAP_NOMATCH
;
1048 route_match_probability_compile (const char *arg
)
1054 lobule
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (long));
1058 case 0: *lobule
= 0; break;
1059 case 100: *lobule
= RAND_MAX
; break;
1060 default: *lobule
= RAND_MAX
/ 100 * perc
;
1067 route_match_probability_free (void *rule
)
1069 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1072 struct route_map_rule_cmd route_match_probability_cmd
=
1075 route_match_probability
,
1076 route_match_probability_compile
,
1077 route_match_probability_free
1080 /* `match interface IFNAME' */
1081 /* Match function should return 1 if match is success else return
1083 static route_map_result_t
1084 route_match_interface (void *rule
, struct prefix
*prefix
,
1085 route_map_object_t type
, void *object
)
1087 struct interface
*ifp
;
1088 struct bgp_info
*info
;
1090 if (type
== RMAP_BGP
)
1094 if (!info
|| !info
->attr
)
1095 return RMAP_NOMATCH
;
1097 ifp
= if_lookup_by_name_all_vrf ((char *)rule
);
1099 if (ifp
== NULL
|| ifp
->ifindex
!= info
->attr
->nh_ifindex
)
1100 return RMAP_NOMATCH
;
1104 return RMAP_NOMATCH
;
1107 /* Route map `interface' match statement. `arg' should be
1110 route_match_interface_compile (const char *arg
)
1112 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1115 /* Free route map's compiled `interface' value. */
1117 route_match_interface_free (void *rule
)
1119 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1122 /* Route map commands for ip address matching. */
1123 struct route_map_rule_cmd route_match_interface_cmd
=
1126 route_match_interface
,
1127 route_match_interface_compile
,
1128 route_match_interface_free
1133 /* `set ip next-hop IP_ADDRESS' */
1135 /* Match function return 1 if match is success else return zero. */
1136 static route_map_result_t
1137 route_match_tag (void *rule
, struct prefix
*prefix
,
1138 route_map_object_t type
, void *object
)
1141 struct bgp_info
*bgp_info
;
1143 if (type
== RMAP_BGP
)
1148 return ((bgp_info
->attr
->tag
== *tag
)? RMAP_MATCH
: RMAP_NOMATCH
);
1151 return RMAP_NOMATCH
;
1155 /* Route map commands for tag matching. */
1156 static struct route_map_rule_cmd route_match_tag_cmd
=
1160 route_map_rule_tag_compile
,
1161 route_map_rule_tag_free
,
1165 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1166 struct rmap_ip_nexthop_set
1168 struct in_addr
*address
;
1173 static route_map_result_t
1174 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
1175 route_map_object_t type
, void *object
)
1177 struct rmap_ip_nexthop_set
*rins
= rule
;
1178 struct bgp_info
*bgp_info
;
1181 if (type
== RMAP_BGP
)
1184 peer
= bgp_info
->peer
;
1186 if (rins
->unchanged
)
1188 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1189 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1191 else if (rins
->peer_address
)
1193 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
1194 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1196 && sockunion_family (peer
->su_remote
) == AF_INET
)
1198 bgp_info
->attr
->nexthop
.s_addr
= sockunion2ip (peer
->su_remote
);
1199 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1201 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
1203 /* The next hop value will be set as part of packet rewrite.
1204 * Set the flags here to indicate that rewrite needs to be done.
1205 * Also, clear the value.
1207 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1208 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1209 bgp_info
->attr
->nexthop
.s_addr
= 0;
1214 /* Set next hop value. */
1215 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1216 bgp_info
->attr
->nexthop
= *rins
->address
;
1217 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1218 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1225 /* Route map `ip nexthop' compile function. Given string is converted
1226 to struct in_addr structure. */
1228 route_set_ip_nexthop_compile (const char *arg
)
1230 struct rmap_ip_nexthop_set
*rins
;
1231 struct in_addr
*address
= NULL
;
1232 int peer_address
= 0;
1236 if (strcmp (arg
, "peer-address") == 0)
1238 else if (strcmp (arg
, "unchanged") == 0)
1242 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
1243 ret
= inet_aton (arg
, address
);
1247 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
1252 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_ip_nexthop_set
));
1254 rins
->address
= address
;
1255 rins
->peer_address
= peer_address
;
1256 rins
->unchanged
= unchanged
;
1261 /* Free route map's compiled `ip nexthop' value. */
1263 route_set_ip_nexthop_free (void *rule
)
1265 struct rmap_ip_nexthop_set
*rins
= rule
;
1268 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1270 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
);
1273 /* Route map commands for ip nexthop set. */
1274 struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
1277 route_set_ip_nexthop
,
1278 route_set_ip_nexthop_compile
,
1279 route_set_ip_nexthop_free
1282 /* `set local-preference LOCAL_PREF' */
1284 /* Set local preference. */
1285 static route_map_result_t
1286 route_set_local_pref (void *rule
, struct prefix
*prefix
,
1287 route_map_object_t type
, void *object
)
1289 struct rmap_value
*rv
;
1290 struct bgp_info
*bgp_info
;
1291 u_int32_t locpref
= 0;
1293 if (type
== RMAP_BGP
)
1295 /* Fetch routemap's rule information. */
1299 /* Set local preference value. */
1300 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
1301 locpref
= bgp_info
->attr
->local_pref
;
1303 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1304 bgp_info
->attr
->local_pref
= route_value_adjust(rv
, locpref
, bgp_info
->peer
);
1310 /* Set local preference rule structure. */
1311 struct route_map_rule_cmd route_set_local_pref_cmd
=
1314 route_set_local_pref
,
1315 route_value_compile
,
1319 /* `set weight WEIGHT' */
1322 static route_map_result_t
1323 route_set_weight (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
1326 struct rmap_value
*rv
;
1327 struct bgp_info
*bgp_info
;
1329 if (type
== RMAP_BGP
)
1331 /* Fetch routemap's rule information. */
1335 /* Set weight value. */
1336 bgp_info
->attr
->weight
= route_value_adjust(rv
, 0, bgp_info
->peer
);
1342 /* Set local preference rule structure. */
1343 struct route_map_rule_cmd route_set_weight_cmd
=
1347 route_value_compile
,
1351 /* `set metric METRIC' */
1353 /* Set metric to attribute. */
1354 static route_map_result_t
1355 route_set_metric (void *rule
, struct prefix
*prefix
,
1356 route_map_object_t type
, void *object
)
1358 struct rmap_value
*rv
;
1359 struct bgp_info
*bgp_info
;
1362 if (type
== RMAP_BGP
)
1364 /* Fetch routemap's rule information. */
1368 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1369 med
= bgp_info
->attr
->med
;
1371 bgp_info
->attr
->med
= route_value_adjust(rv
, med
, bgp_info
->peer
);
1372 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
1377 /* Set metric rule structure. */
1378 struct route_map_rule_cmd route_set_metric_cmd
=
1382 route_value_compile
,
1386 /* `set as-path prepend ASPATH' */
1388 /* For AS path prepend mechanism. */
1389 static route_map_result_t
1390 route_set_aspath_prepend (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1392 struct aspath
*aspath
;
1394 struct bgp_info
*binfo
;
1396 if (type
== RMAP_BGP
)
1400 if (binfo
->attr
->aspath
->refcnt
)
1401 new = aspath_dup (binfo
->attr
->aspath
);
1403 new = binfo
->attr
->aspath
;
1405 if ((uintptr_t)rule
> 10)
1408 aspath_prepend (aspath
, new);
1412 as_t as
= aspath_leftmost(new);
1413 if (!as
) as
= binfo
->peer
->as
;
1414 new = aspath_add_seq_n (new, as
, (uintptr_t) rule
);
1417 binfo
->attr
->aspath
= new;
1424 route_set_aspath_prepend_compile (const char *arg
)
1428 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
<= 10)
1429 return (void*)(uintptr_t)num
;
1431 return route_aspath_compile(arg
);
1435 route_set_aspath_prepend_free (void *rule
)
1437 if ((uintptr_t)rule
> 10)
1438 route_aspath_free(rule
);
1442 /* Set as-path prepend rule structure. */
1443 struct route_map_rule_cmd route_set_aspath_prepend_cmd
=
1446 route_set_aspath_prepend
,
1447 route_set_aspath_prepend_compile
,
1448 route_set_aspath_prepend_free
,
1451 /* `set as-path exclude ASn' */
1453 /* For ASN exclude mechanism.
1454 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1455 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1457 static route_map_result_t
1458 route_set_aspath_exclude (void *rule
, struct prefix
*dummy
, route_map_object_t type
, void *object
)
1460 struct aspath
* new_path
, * exclude_path
;
1461 struct bgp_info
*binfo
;
1463 if (type
== RMAP_BGP
)
1465 exclude_path
= rule
;
1467 if (binfo
->attr
->aspath
->refcnt
)
1468 new_path
= aspath_dup (binfo
->attr
->aspath
);
1470 new_path
= binfo
->attr
->aspath
;
1471 binfo
->attr
->aspath
= aspath_filter_exclude (new_path
, exclude_path
);
1476 /* Set ASn exlude rule structure. */
1477 struct route_map_rule_cmd route_set_aspath_exclude_cmd
=
1480 route_set_aspath_exclude
,
1481 route_aspath_compile
,
1485 /* `set community COMMUNITY' */
1488 struct community
*com
;
1493 /* For community set mechanism. */
1494 static route_map_result_t
1495 route_set_community (void *rule
, struct prefix
*prefix
,
1496 route_map_object_t type
, void *object
)
1498 struct rmap_com_set
*rcs
;
1499 struct bgp_info
*binfo
;
1501 struct community
*new = NULL
;
1502 struct community
*old
;
1503 struct community
*merge
;
1505 if (type
== RMAP_BGP
)
1510 old
= attr
->community
;
1515 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
));
1516 attr
->community
= NULL
;
1517 /* See the longer comment down below. */
1518 if (old
&& old
->refcnt
== 0)
1519 community_free(old
);
1523 /* "additive" case. */
1524 if (rcs
->additive
&& old
)
1526 merge
= community_merge (community_dup (old
), rcs
->com
);
1528 /* HACK: if the old community is not intern'd,
1529 * we should free it here, or all reference to it may be lost.
1530 * Really need to cleanup attribute caching sometime.
1532 if (old
->refcnt
== 0)
1533 community_free (old
);
1534 new = community_uniq_sort (merge
);
1535 community_free (merge
);
1538 new = community_dup (rcs
->com
);
1540 /* will be interned by caller if required */
1541 attr
->community
= new;
1543 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1549 /* Compile function for set community. */
1551 route_set_community_compile (const char *arg
)
1553 struct rmap_com_set
*rcs
;
1554 struct community
*com
= NULL
;
1559 if (strcmp (arg
, "none") == 0)
1563 sp
= strstr (arg
, "additive");
1567 /* "additive" keyworkd is included. */
1572 com
= community_str2com (arg
);
1581 rcs
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_com_set
));
1583 rcs
->additive
= additive
;
1589 /* Free function for set community. */
1591 route_set_community_free (void *rule
)
1593 struct rmap_com_set
*rcs
= rule
;
1596 community_free (rcs
->com
);
1597 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1600 /* Set community rule structure. */
1601 struct route_map_rule_cmd route_set_community_cmd
=
1604 route_set_community
,
1605 route_set_community_compile
,
1606 route_set_community_free
,
1609 /* `set community COMMUNITY' */
1610 struct rmap_lcom_set
1612 struct lcommunity
*lcom
;
1618 /* For lcommunity set mechanism. */
1619 static route_map_result_t
1620 route_set_lcommunity (void *rule
, struct prefix
*prefix
,
1621 route_map_object_t type
, void *object
)
1623 struct rmap_lcom_set
*rcs
;
1624 struct bgp_info
*binfo
;
1626 struct lcommunity
*new = NULL
;
1627 struct lcommunity
*old
;
1628 struct lcommunity
*merge
;
1630 if (type
== RMAP_BGP
)
1635 old
= attr
->lcommunity
;
1640 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
));
1641 attr
->lcommunity
= NULL
;
1643 /* See the longer comment down below. */
1644 if (old
&& old
->refcnt
== 0)
1645 lcommunity_free(&old
);
1649 if (rcs
->additive
&& old
)
1651 merge
= lcommunity_merge (lcommunity_dup (old
), rcs
->lcom
);
1653 /* HACK: if the old large-community is not intern'd,
1654 * we should free it here, or all reference to it may be lost.
1655 * Really need to cleanup attribute caching sometime.
1657 if (old
->refcnt
== 0)
1658 lcommunity_free (&old
);
1659 new = lcommunity_uniq_sort (merge
);
1660 lcommunity_free (&merge
);
1663 new = lcommunity_dup (rcs
->lcom
);
1665 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1666 attr
->lcommunity
= new;
1668 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
);
1674 /* Compile function for set community. */
1676 route_set_lcommunity_compile (const char *arg
)
1678 struct rmap_lcom_set
*rcs
;
1679 struct lcommunity
*lcom
= NULL
;
1684 if (strcmp (arg
, "none") == 0)
1688 sp
= strstr (arg
, "additive");
1692 /* "additive" keyworkd is included. */
1697 lcom
= lcommunity_str2com (arg
);
1706 rcs
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_com_set
));
1708 rcs
->additive
= additive
;
1714 /* Free function for set lcommunity. */
1716 route_set_lcommunity_free (void *rule
)
1718 struct rmap_lcom_set
*rcs
= rule
;
1721 lcommunity_free (&rcs
->lcom
);
1723 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1726 /* Set community rule structure. */
1727 struct route_map_rule_cmd route_set_lcommunity_cmd
=
1730 route_set_lcommunity
,
1731 route_set_lcommunity_compile
,
1732 route_set_lcommunity_free
,
1735 /* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
1737 /* For large community set mechanism. */
1738 static route_map_result_t
1739 route_set_lcommunity_delete (void *rule
, struct prefix
*prefix
,
1740 route_map_object_t type
, void *object
)
1742 struct community_list
*list
;
1743 struct lcommunity
*merge
;
1744 struct lcommunity
*new;
1745 struct lcommunity
*old
;
1746 struct bgp_info
*binfo
;
1748 if (type
== RMAP_BGP
)
1754 list
= community_list_lookup (bgp_clist
, rule
,
1755 LARGE_COMMUNITY_LIST_MASTER
);
1756 old
= binfo
->attr
->lcommunity
;
1760 merge
= lcommunity_list_match_delete (lcommunity_dup (old
), list
);
1761 new = lcommunity_uniq_sort (merge
);
1762 lcommunity_free (&merge
);
1764 /* HACK: if the old community is not intern'd,
1765 * we should free it here, or all reference to it may be lost.
1766 * Really need to cleanup attribute caching sometime.
1768 if (old
->refcnt
== 0)
1769 lcommunity_free (&old
);
1773 binfo
->attr
->lcommunity
= NULL
;
1774 binfo
->attr
->flag
&= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
);
1775 lcommunity_free (&new);
1779 binfo
->attr
->lcommunity
= new;
1780 binfo
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES
);
1788 /* Compile function for set lcommunity. */
1790 route_set_lcommunity_delete_compile (const char *arg
)
1796 p
= strchr (arg
, ' ');
1800 str
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1801 memcpy (str
, arg
, len
);
1809 /* Free function for set lcommunity. */
1811 route_set_lcommunity_delete_free (void *rule
)
1813 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1816 /* Set lcommunity rule structure. */
1817 struct route_map_rule_cmd route_set_lcommunity_delete_cmd
=
1820 route_set_lcommunity_delete
,
1821 route_set_lcommunity_delete_compile
,
1822 route_set_lcommunity_delete_free
,
1826 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
1828 /* For community set mechanism. */
1829 static route_map_result_t
1830 route_set_community_delete (void *rule
, struct prefix
*prefix
,
1831 route_map_object_t type
, void *object
)
1833 struct community_list
*list
;
1834 struct community
*merge
;
1835 struct community
*new;
1836 struct community
*old
;
1837 struct bgp_info
*binfo
;
1839 if (type
== RMAP_BGP
)
1845 list
= community_list_lookup (bgp_clist
, rule
, COMMUNITY_LIST_MASTER
);
1846 old
= binfo
->attr
->community
;
1850 merge
= community_list_match_delete (community_dup (old
), list
);
1851 new = community_uniq_sort (merge
);
1852 community_free (merge
);
1854 /* HACK: if the old community is not intern'd,
1855 * we should free it here, or all reference to it may be lost.
1856 * Really need to cleanup attribute caching sometime.
1858 if (old
->refcnt
== 0)
1859 community_free (old
);
1863 binfo
->attr
->community
= NULL
;
1864 binfo
->attr
->flag
&= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1865 community_free (new);
1869 binfo
->attr
->community
= new;
1870 binfo
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1878 /* Compile function for set community. */
1880 route_set_community_delete_compile (const char *arg
)
1886 p
= strchr (arg
, ' ');
1890 str
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1891 memcpy (str
, arg
, len
);
1899 /* Free function for set community. */
1901 route_set_community_delete_free (void *rule
)
1903 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1906 /* Set community rule structure. */
1907 struct route_map_rule_cmd route_set_community_delete_cmd
=
1910 route_set_community_delete
,
1911 route_set_community_delete_compile
,
1912 route_set_community_delete_free
,
1915 /* `set extcommunity rt COMMUNITY' */
1917 /* For community set mechanism. Used by _rt and _soo. */
1918 static route_map_result_t
1919 route_set_ecommunity (void *rule
, struct prefix
*prefix
,
1920 route_map_object_t type
, void *object
)
1922 struct ecommunity
*ecom
;
1923 struct ecommunity
*new_ecom
;
1924 struct ecommunity
*old_ecom
;
1925 struct bgp_info
*bgp_info
;
1927 if (type
== RMAP_BGP
)
1935 /* We assume additive for Extended Community. */
1936 old_ecom
= bgp_info
->attr
->ecommunity
;
1940 new_ecom
= ecommunity_merge (ecommunity_dup (old_ecom
), ecom
);
1942 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1943 * ->refcnt = 0 => set by a previous route-map statement */
1944 if (!old_ecom
->refcnt
)
1945 ecommunity_free (&old_ecom
);
1948 new_ecom
= ecommunity_dup (ecom
);
1950 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1951 bgp_info
->attr
->ecommunity
= new_ecom
;
1953 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
);
1958 /* Compile function for set community. */
1960 route_set_ecommunity_rt_compile (const char *arg
)
1962 struct ecommunity
*ecom
;
1964 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
1967 return ecommunity_intern (ecom
);
1970 /* Free function for set community. Used by _rt and _soo */
1972 route_set_ecommunity_free (void *rule
)
1974 struct ecommunity
*ecom
= rule
;
1975 ecommunity_unintern (&ecom
);
1978 /* Set community rule structure. */
1979 struct route_map_rule_cmd route_set_ecommunity_rt_cmd
=
1982 route_set_ecommunity
,
1983 route_set_ecommunity_rt_compile
,
1984 route_set_ecommunity_free
,
1987 /* `set extcommunity soo COMMUNITY' */
1989 /* Compile function for set community. */
1991 route_set_ecommunity_soo_compile (const char *arg
)
1993 struct ecommunity
*ecom
;
1995 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
1999 return ecommunity_intern (ecom
);
2002 /* Set community rule structure. */
2003 struct route_map_rule_cmd route_set_ecommunity_soo_cmd
=
2006 route_set_ecommunity
,
2007 route_set_ecommunity_soo_compile
,
2008 route_set_ecommunity_free
,
2011 /* `set origin ORIGIN' */
2013 /* For origin set. */
2014 static route_map_result_t
2015 route_set_origin (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
2018 struct bgp_info
*bgp_info
;
2020 if (type
== RMAP_BGP
)
2025 bgp_info
->attr
->origin
= *origin
;
2031 /* Compile function for origin set. */
2033 route_set_origin_compile (const char *arg
)
2037 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
2039 if (strcmp (arg
, "igp") == 0)
2041 else if (strcmp (arg
, "egp") == 0)
2049 /* Compile function for origin set. */
2051 route_set_origin_free (void *rule
)
2053 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2056 /* Set origin rule structure. */
2057 struct route_map_rule_cmd route_set_origin_cmd
=
2061 route_set_origin_compile
,
2062 route_set_origin_free
,
2065 /* `set atomic-aggregate' */
2067 /* For atomic aggregate set. */
2068 static route_map_result_t
2069 route_set_atomic_aggregate (void *rule
, struct prefix
*prefix
,
2070 route_map_object_t type
, void *object
)
2072 struct bgp_info
*bgp_info
;
2074 if (type
== RMAP_BGP
)
2077 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
2083 /* Compile function for atomic aggregate. */
2085 route_set_atomic_aggregate_compile (const char *arg
)
2090 /* Compile function for atomic aggregate. */
2092 route_set_atomic_aggregate_free (void *rule
)
2097 /* Set atomic aggregate rule structure. */
2098 struct route_map_rule_cmd route_set_atomic_aggregate_cmd
=
2101 route_set_atomic_aggregate
,
2102 route_set_atomic_aggregate_compile
,
2103 route_set_atomic_aggregate_free
,
2106 /* `set aggregator as AS A.B.C.D' */
2110 struct in_addr address
;
2113 static route_map_result_t
2114 route_set_aggregator_as (void *rule
, struct prefix
*prefix
,
2115 route_map_object_t type
, void *object
)
2117 struct bgp_info
*bgp_info
;
2118 struct aggregator
*aggregator
;
2120 if (type
== RMAP_BGP
)
2125 bgp_info
->attr
->aggregator_as
= aggregator
->as
;
2126 bgp_info
->attr
->aggregator_addr
= aggregator
->address
;
2127 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
);
2134 route_set_aggregator_as_compile (const char *arg
)
2136 struct aggregator
*aggregator
;
2141 aggregator
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct aggregator
));
2142 sscanf (arg
, "%s %s", as
, address
);
2144 aggregator
->as
= strtoul (as
, NULL
, 10);
2145 ret
= inet_aton (address
, &aggregator
->address
);
2148 XFREE (MTYPE_ROUTE_MAP_COMPILED
, aggregator
);
2155 route_set_aggregator_as_free (void *rule
)
2157 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2160 struct route_map_rule_cmd route_set_aggregator_as_cmd
=
2163 route_set_aggregator_as
,
2164 route_set_aggregator_as_compile
,
2165 route_set_aggregator_as_free
,
2168 /* Set tag to object. object must be pointer to struct bgp_info */
2169 static route_map_result_t
2170 route_set_tag (void *rule
, struct prefix
*prefix
,
2171 route_map_object_t type
, void *object
)
2174 struct bgp_info
*bgp_info
;
2176 if (type
== RMAP_BGP
)
2182 bgp_info
->attr
->tag
=*tag
;
2189 /* Route map commands for tag set. */
2190 static struct route_map_rule_cmd route_set_tag_cmd
=
2194 route_map_rule_tag_compile
,
2195 route_map_rule_tag_free
,
2198 /* Set label-index to object. object must be pointer to struct bgp_info */
2199 static route_map_result_t
2200 route_set_label_index (void *rule
, struct prefix
*prefix
,
2201 route_map_object_t type
, void *object
)
2203 struct rmap_value
*rv
;
2204 struct bgp_info
*bgp_info
;
2205 u_int32_t label_index
;
2207 if (type
== RMAP_BGP
)
2209 /* Fetch routemap's rule information. */
2213 /* Set label-index value. */
2214 label_index
= rv
->value
;
2217 bgp_info
->attr
->label_index
= label_index
;
2218 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID
);
2225 /* Route map commands for label-index set. */
2226 static struct route_map_rule_cmd route_set_label_index_cmd
=
2229 route_set_label_index
,
2230 route_value_compile
,
2234 /* `match ipv6 address IP_ACCESS_LIST' */
2236 static route_map_result_t
2237 route_match_ipv6_address (void *rule
, struct prefix
*prefix
,
2238 route_map_object_t type
, void *object
)
2240 struct access_list
*alist
;
2242 if (type
== RMAP_BGP
)
2244 alist
= access_list_lookup (AFI_IP6
, (char *) rule
);
2246 return RMAP_NOMATCH
;
2248 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
2249 RMAP_NOMATCH
: RMAP_MATCH
);
2251 return RMAP_NOMATCH
;
2255 route_match_ipv6_address_compile (const char *arg
)
2257 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2261 route_match_ipv6_address_free (void *rule
)
2263 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2266 /* Route map commands for ip address matching. */
2267 struct route_map_rule_cmd route_match_ipv6_address_cmd
=
2270 route_match_ipv6_address
,
2271 route_match_ipv6_address_compile
,
2272 route_match_ipv6_address_free
2275 /* `match ipv6 next-hop IP_ADDRESS' */
2277 static route_map_result_t
2278 route_match_ipv6_next_hop (void *rule
, struct prefix
*prefix
,
2279 route_map_object_t type
, void *object
)
2281 struct in6_addr
*addr
= rule
;
2282 struct bgp_info
*bgp_info
;
2284 if (type
== RMAP_BGP
)
2288 if (IPV6_ADDR_SAME (&bgp_info
->attr
->mp_nexthop_global
, addr
))
2291 if (bgp_info
->attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
&&
2292 IPV6_ADDR_SAME (&bgp_info
->attr
->mp_nexthop_local
, rule
))
2295 return RMAP_NOMATCH
;
2298 return RMAP_NOMATCH
;
2302 route_match_ipv6_next_hop_compile (const char *arg
)
2304 struct in6_addr
*address
;
2307 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2309 ret
= inet_pton (AF_INET6
, arg
, address
);
2312 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2320 route_match_ipv6_next_hop_free (void *rule
)
2322 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2325 struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
=
2328 route_match_ipv6_next_hop
,
2329 route_match_ipv6_next_hop_compile
,
2330 route_match_ipv6_next_hop_free
2333 /* `match ipv6 address prefix-list PREFIX_LIST' */
2335 static route_map_result_t
2336 route_match_ipv6_address_prefix_list (void *rule
, struct prefix
*prefix
,
2337 route_map_object_t type
, void *object
)
2339 struct prefix_list
*plist
;
2341 if (type
== RMAP_BGP
)
2343 plist
= prefix_list_lookup (AFI_IP6
, (char *) rule
);
2345 return RMAP_NOMATCH
;
2347 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
2348 RMAP_NOMATCH
: RMAP_MATCH
);
2350 return RMAP_NOMATCH
;
2354 route_match_ipv6_address_prefix_list_compile (const char *arg
)
2356 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2360 route_match_ipv6_address_prefix_list_free (void *rule
)
2362 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2365 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
=
2367 "ipv6 address prefix-list",
2368 route_match_ipv6_address_prefix_list
,
2369 route_match_ipv6_address_prefix_list_compile
,
2370 route_match_ipv6_address_prefix_list_free
2373 /* `set ipv6 nexthop global IP_ADDRESS' */
2375 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2376 static route_map_result_t
2377 route_set_ipv6_nexthop_global (void *rule
, struct prefix
*prefix
,
2378 route_map_object_t type
, void *object
)
2380 struct in6_addr
*address
;
2381 struct bgp_info
*bgp_info
;
2383 if (type
== RMAP_BGP
)
2385 /* Fetch routemap's rule information. */
2389 /* Set next hop value. */
2390 bgp_info
->attr
->mp_nexthop_global
= *address
;
2392 /* Set nexthop length. */
2393 if (bgp_info
->attr
->mp_nexthop_len
== 0)
2394 bgp_info
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
2396 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2397 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
2403 /* Route map `ip next-hop' compile function. Given string is converted
2404 to struct in_addr structure. */
2406 route_set_ipv6_nexthop_global_compile (const char *arg
)
2409 struct in6_addr
*address
;
2411 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2413 ret
= inet_pton (AF_INET6
, arg
, address
);
2417 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2424 /* Free route map's compiled `ip next-hop' value. */
2426 route_set_ipv6_nexthop_global_free (void *rule
)
2428 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2431 /* Route map commands for ip nexthop set. */
2432 struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd
=
2434 "ipv6 next-hop global",
2435 route_set_ipv6_nexthop_global
,
2436 route_set_ipv6_nexthop_global_compile
,
2437 route_set_ipv6_nexthop_global_free
2440 /* Set next-hop preference value. */
2441 static route_map_result_t
2442 route_set_ipv6_nexthop_prefer_global (void *rule
, struct prefix
*prefix
,
2443 route_map_object_t type
, void *object
)
2445 struct bgp_info
*bgp_info
;
2448 if (type
== RMAP_BGP
)
2450 /* Fetch routemap's rule information. */
2452 peer
= bgp_info
->peer
;
2454 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2455 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2457 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2459 /* Set next hop preference to global */
2460 bgp_info
->attr
->mp_nexthop_prefer_global
= TRUE
;
2461 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2462 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2466 bgp_info
->attr
->mp_nexthop_prefer_global
= FALSE
;
2467 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2468 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2475 route_set_ipv6_nexthop_prefer_global_compile (const char *arg
)
2479 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2485 /* Free route map's compiled `ip next-hop' value. */
2487 route_set_ipv6_nexthop_prefer_global_free (void *rule
)
2489 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2492 /* Route map commands for ip nexthop set preferred. */
2493 struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd
=
2495 "ipv6 next-hop prefer-global",
2496 route_set_ipv6_nexthop_prefer_global
,
2497 route_set_ipv6_nexthop_prefer_global_compile
,
2498 route_set_ipv6_nexthop_prefer_global_free
2501 /* `set ipv6 nexthop local IP_ADDRESS' */
2503 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2504 static route_map_result_t
2505 route_set_ipv6_nexthop_local (void *rule
, struct prefix
*prefix
,
2506 route_map_object_t type
, void *object
)
2508 struct in6_addr
*address
;
2509 struct bgp_info
*bgp_info
;
2511 if (type
== RMAP_BGP
)
2513 /* Fetch routemap's rule information. */
2517 /* Set next hop value. */
2518 bgp_info
->attr
->mp_nexthop_local
= *address
;
2520 /* Set nexthop length. */
2521 if (bgp_info
->attr
->mp_nexthop_len
!= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
2522 bgp_info
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
2524 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2525 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
2531 /* Route map `ip nexthop' compile function. Given string is converted
2532 to struct in_addr structure. */
2534 route_set_ipv6_nexthop_local_compile (const char *arg
)
2537 struct in6_addr
*address
;
2539 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2541 ret
= inet_pton (AF_INET6
, arg
, address
);
2545 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2552 /* Free route map's compiled `ip nexthop' value. */
2554 route_set_ipv6_nexthop_local_free (void *rule
)
2556 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2559 /* Route map commands for ip nexthop set. */
2560 struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
2562 "ipv6 next-hop local",
2563 route_set_ipv6_nexthop_local
,
2564 route_set_ipv6_nexthop_local_compile
,
2565 route_set_ipv6_nexthop_local_free
2568 /* `set ipv6 nexthop peer-address' */
2570 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2571 static route_map_result_t
2572 route_set_ipv6_nexthop_peer (void *rule
, struct prefix
*prefix
,
2573 route_map_object_t type
, void *object
)
2575 struct in6_addr peer_address
;
2576 struct bgp_info
*bgp_info
;
2579 if (type
== RMAP_BGP
)
2581 /* Fetch routemap's rule information. */
2583 peer
= bgp_info
->peer
;
2585 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2586 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2588 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2590 peer_address
= peer
->su_remote
->sin6
.sin6_addr
;
2591 /* Set next hop value and length in attribute. */
2592 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
))
2594 bgp_info
->attr
->mp_nexthop_local
= peer_address
;
2595 if (bgp_info
->attr
->mp_nexthop_len
!= 32)
2596 bgp_info
->attr
->mp_nexthop_len
= 32;
2600 bgp_info
->attr
->mp_nexthop_global
= peer_address
;
2601 if (bgp_info
->attr
->mp_nexthop_len
== 0)
2602 bgp_info
->attr
->mp_nexthop_len
= 16;
2606 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
2608 /* The next hop value will be set as part of packet rewrite.
2609 * Set the flags here to indicate that rewrite needs to be done.
2610 * Also, clear the value - we clear both global and link-local
2611 * nexthops, whether we send one or both is determined elsewhere.
2613 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2614 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
2615 /* clear next hop value. */
2616 memset (&(bgp_info
->attr
->mp_nexthop_global
),
2617 0, sizeof (struct in6_addr
));
2618 memset (&(bgp_info
->attr
->mp_nexthop_local
),
2619 0, sizeof (struct in6_addr
));
2626 /* Route map `ip next-hop' compile function. Given string is converted
2627 to struct in_addr structure. */
2629 route_set_ipv6_nexthop_peer_compile (const char *arg
)
2633 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2639 /* Free route map's compiled `ip next-hop' value. */
2641 route_set_ipv6_nexthop_peer_free (void *rule
)
2643 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2646 /* Route map commands for ip nexthop set. */
2647 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
=
2649 "ipv6 next-hop peer-address",
2650 route_set_ipv6_nexthop_peer
,
2651 route_set_ipv6_nexthop_peer_compile
,
2652 route_set_ipv6_nexthop_peer_free
2655 /* `set ip vpn nexthop A.B.C.D' */
2657 static route_map_result_t
2658 route_set_vpnv4_nexthop (void *rule
, struct prefix
*prefix
,
2659 route_map_object_t type
, void *object
)
2661 struct in_addr
*address
;
2662 struct bgp_info
*bgp_info
;
2664 if (type
== RMAP_BGP
)
2666 /* Fetch routemap's rule information. */
2670 /* Set next hop value. */
2671 bgp_info
->attr
->mp_nexthop_global_in
= *address
;
2672 bgp_info
->attr
->mp_nexthop_len
= 4;
2679 route_set_vpnv4_nexthop_compile (const char *arg
)
2682 struct in_addr
*address
;
2684 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2686 ret
= inet_aton (arg
, address
);
2690 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2697 /* `set ipv6 vpn nexthop A.B.C.D' */
2699 static route_map_result_t
2700 route_set_vpnv6_nexthop (void *rule
, struct prefix
*prefix
,
2701 route_map_object_t type
, void *object
)
2703 struct in6_addr
*address
;
2704 struct bgp_info
*bgp_info
;
2706 if (type
== RMAP_BGP
)
2708 /* Fetch routemap's rule information. */
2712 /* Set next hop value. */
2713 memcpy (&bgp_info
->attr
->mp_nexthop_global
, address
, sizeof(struct in6_addr
));
2714 bgp_info
->attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_VPNV6_GLOBAL
;
2721 route_set_vpnv6_nexthop_compile (const char *arg
)
2724 struct in6_addr
*address
;
2726 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2727 ret
= inet_pton (AF_INET6
, arg
, address
);
2731 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2739 route_set_vpn_nexthop_free (void *rule
)
2741 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2744 /* Route map commands for ip nexthop set. */
2745 struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
=
2748 route_set_vpnv4_nexthop
,
2749 route_set_vpnv4_nexthop_compile
,
2750 route_set_vpn_nexthop_free
2753 /* Route map commands for ip nexthop set. */
2754 struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd
=
2756 "ipv6 vpn next-hop",
2757 route_set_vpnv6_nexthop
,
2758 route_set_vpnv6_nexthop_compile
,
2759 route_set_vpn_nexthop_free
2762 /* `set originator-id' */
2764 /* For origin set. */
2765 static route_map_result_t
2766 route_set_originator_id (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
2768 struct in_addr
*address
;
2769 struct bgp_info
*bgp_info
;
2771 if (type
== RMAP_BGP
)
2776 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
);
2777 bgp_info
->attr
->originator_id
= *address
;
2783 /* Compile function for originator-id set. */
2785 route_set_originator_id_compile (const char *arg
)
2788 struct in_addr
*address
;
2790 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2792 ret
= inet_aton (arg
, address
);
2796 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2803 /* Compile function for originator_id set. */
2805 route_set_originator_id_free (void *rule
)
2807 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2810 /* Set originator-id rule structure. */
2811 struct route_map_rule_cmd route_set_originator_id_cmd
=
2814 route_set_originator_id
,
2815 route_set_originator_id_compile
,
2816 route_set_originator_id_free
,
2819 /* Add bgp route map rule. */
2821 bgp_route_match_add (struct vty
*vty
,
2822 const char *command
, const char *arg
,
2823 route_map_event_t type
)
2825 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
2828 ret
= route_map_add_match (index
, command
, arg
);
2833 case RMAP_RULE_MISSING
:
2834 vty_outln (vty
, "%% BGP Can't find rule.");
2835 return CMD_WARNING_CONFIG_FAILED
;
2836 case RMAP_COMPILE_ERROR
:
2837 vty_outln (vty
, "%% BGP Argument is malformed.");
2838 return CMD_WARNING_CONFIG_FAILED
;
2842 if (type
!= RMAP_EVENT_MATCH_ADDED
)
2844 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
2850 /* Delete bgp route map rule. */
2852 bgp_route_match_delete (struct vty
*vty
,
2853 const char *command
, const char *arg
,
2854 route_map_event_t type
)
2856 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
2858 char *dep_name
= NULL
;
2860 char *rmap_name
= NULL
;
2862 if (type
!= RMAP_EVENT_MATCH_DELETED
)
2864 /* ignore the mundane, the types without any dependency */
2867 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
2868 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
2872 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
2874 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
2877 ret
= route_map_delete_match (index
, command
, dep_name
);
2882 case RMAP_RULE_MISSING
:
2883 vty_outln (vty
, "%% BGP Can't find rule.");
2885 case RMAP_COMPILE_ERROR
:
2886 vty_outln (vty
, "%% BGP Argument is malformed.");
2890 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2892 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2893 return CMD_WARNING_CONFIG_FAILED
;
2896 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
2897 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
2900 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2902 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2908 * This is the workhorse routine for processing in/out routemap
2912 bgp_route_map_process_peer (const char *rmap_name
, struct route_map
*map
,
2913 struct peer
*peer
, int afi
, int safi
,
2918 struct bgp_filter
*filter
;
2920 if (!peer
|| !rmap_name
)
2923 filter
= &peer
->filter
[afi
][safi
];
2925 * in is for non-route-server clients,
2926 * out is for all peers
2928 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2930 if (filter
->map
[RMAP_IN
].name
&&
2931 (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0))
2933 filter
->map
[RMAP_IN
].map
= map
;
2935 if (route_update
&& peer
->status
== Established
)
2937 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2938 PEER_FLAG_SOFT_RECONFIG
))
2940 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2941 zlog_debug("Processing route_map %s update on "
2942 "peer %s (inbound, soft-reconfig)",
2943 rmap_name
, peer
->host
);
2945 bgp_soft_reconfig_in (peer
, afi
, safi
);
2947 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2948 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2951 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2952 zlog_debug("Processing route_map %s update on "
2953 "peer %s (inbound, route-refresh)",
2954 rmap_name
, peer
->host
);
2955 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2961 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2965 if (update
&& route_update
&& peer
->status
== Established
)
2967 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2968 PEER_FLAG_SOFT_RECONFIG
))
2970 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2971 zlog_debug("Processing route_map %s update on "
2972 "peer %s (import, soft-reconfig)",
2973 rmap_name
, peer
->host
);
2975 bgp_soft_reconfig_in (peer
, afi
, safi
);
2977 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2978 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2980 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2981 zlog_debug("Processing route_map %s update on "
2982 "peer %s (import, route-refresh)",
2983 rmap_name
, peer
->host
);
2984 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2986 /* DD: Else, what else do we do ? Reset peer ? */
2991 * For outbound, unsuppress and default-originate map change (content or
2992 * map created), merely update the "config" here, the actual route
2993 * announcement happens at the group level.
2995 if (filter
->map
[RMAP_OUT
].name
&&
2996 (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
2997 filter
->map
[RMAP_OUT
].map
= map
;
2999 if (filter
->usmap
.name
&&
3000 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3001 filter
->usmap
.map
= map
;
3003 if (peer
->default_rmap
[afi
][safi
].name
&&
3004 (strcmp (rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
3005 peer
->default_rmap
[afi
][safi
].map
= map
;
3009 bgp_route_map_update_peer_group(const char *rmap_name
, struct route_map
*map
,
3012 struct peer_group
*group
;
3013 struct listnode
*node
, *nnode
;
3014 struct bgp_filter
*filter
;
3021 /* All the peers have been updated correctly already. This is
3022 * just updating the placeholder data. No real update required.
3024 for (ALL_LIST_ELEMENTS (bgp
->group
, node
, nnode
, group
))
3025 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3026 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3028 filter
= &group
->conf
->filter
[afi
][safi
];
3030 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++)
3032 if ((filter
->map
[direct
].name
) &&
3033 (strcmp(rmap_name
, filter
->map
[direct
].name
) == 0))
3034 filter
->map
[direct
].map
= map
;
3037 if (filter
->usmap
.name
&&
3038 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
3039 filter
->usmap
.map
= map
;
3044 * Note that if an extreme number (tens of thousands) of route-maps are in use
3045 * and if bgp has an extreme number of peers, network statements, etc then this
3046 * function can consume a lot of cycles. This is due to this function being
3047 * called for each route-map and within this function we walk the list of peers,
3048 * network statements, etc looking to see if they use this route-map.
3051 bgp_route_map_process_update (struct bgp
*bgp
, const char *rmap_name
, int route_update
)
3057 struct bgp_node
*bn
;
3058 struct bgp_static
*bgp_static
;
3059 struct listnode
*node
, *nnode
;
3060 struct route_map
*map
;
3061 char buf
[INET6_ADDRSTRLEN
];
3063 map
= route_map_lookup_by_name (rmap_name
);
3065 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
3068 /* Ignore dummy peer-group structure */
3069 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3072 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3073 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3075 /* Ignore inactive AFI/SAFI */
3076 if (! peer
->afc
[afi
][safi
])
3079 /* process in/out/import/export/default-orig route-maps */
3080 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
, safi
, route_update
);
3084 /* for outbound/default-orig route-maps, process for groups */
3085 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
3088 /* update peer-group config (template) */
3089 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
3091 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3092 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3094 /* For table route-map updates. */
3095 if (!bgp_fibupd_safi(safi
))
3098 if (bgp
->table_map
[afi
][safi
].name
&&
3099 (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
) == 0))
3101 bgp
->table_map
[afi
][safi
].map
= map
;
3103 if (BGP_DEBUG (zebra
, ZEBRA
))
3104 zlog_debug("Processing route_map %s update on "
3105 "table map", rmap_name
);
3107 bgp_zebra_announce_table(bgp
, afi
, safi
);
3110 /* For network route-map updates. */
3111 for (bn
= bgp_table_top (bgp
->route
[afi
][safi
]); bn
; bn
= bgp_route_next (bn
))
3112 if ((bgp_static
= bn
->info
) != NULL
)
3114 if (bgp_static
->rmap
.name
&&
3115 (strcmp(rmap_name
, bgp_static
->rmap
.name
) == 0))
3117 bgp_static
->rmap
.map
= map
;
3120 if (!bgp_static
->backdoor
)
3122 if (bgp_debug_zebra(&bn
->p
))
3123 zlog_debug("Processing route_map %s update on "
3124 "static route %s", rmap_name
,
3125 inet_ntop (bn
->p
.family
, &bn
->p
.u
.prefix
,
3126 buf
, INET6_ADDRSTRLEN
));
3127 bgp_static_update (bgp
, &bn
->p
, bgp_static
, afi
, safi
);
3133 /* For redistribute route-map updates. */
3134 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3135 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3137 struct list
*red_list
;
3138 struct listnode
*node
;
3139 struct bgp_redist
*red
;
3141 red_list
= bgp
->redist
[afi
][i
];
3145 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
3147 if (red
->rmap
.name
&&
3148 (strcmp(rmap_name
, red
->rmap
.name
) == 0))
3150 red
->rmap
.map
= map
;
3154 if (BGP_DEBUG (zebra
, ZEBRA
))
3155 zlog_debug("Processing route_map %s update on "
3156 "redistributed routes", rmap_name
);
3158 bgp_redistribute_resend (bgp
, afi
, i
, red
->instance
);
3166 bgp_route_map_process_update_cb (char *rmap_name
)
3168 struct listnode
*node
, *nnode
;
3171 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
3172 bgp_route_map_process_update(bgp
, rmap_name
, 1);
3175 zlog_debug("%s: calling vnc_routemap_update", __func__
);
3176 vnc_routemap_update(bgp
, __func__
);
3182 bgp_route_map_update_timer(struct thread
*thread
)
3184 bm
->t_rmap_update
= NULL
;
3186 route_map_walk_update_list(bgp_route_map_process_update_cb
);
3192 bgp_route_map_mark_update (const char *rmap_name
)
3194 if (bm
->t_rmap_update
== NULL
)
3196 struct listnode
*node
, *nnode
;
3199 /* rmap_update_timer of 0 means don't do route updates */
3200 if (bm
->rmap_update_timer
)
3202 bm
->t_rmap_update
= NULL
;
3203 thread_add_timer(bm
->master
, bgp_route_map_update_timer
, NULL
, bm
->rmap_update_timer
,
3204 &bm
->t_rmap_update
);
3206 /* Signal the groups that a route-map update event has started */
3207 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
3208 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
, 1, 1);
3212 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
3213 bgp_route_map_process_update(bgp
, rmap_name
, 0);
3215 zlog_debug("%s: calling vnc_routemap_update", __func__
);
3216 vnc_routemap_update(bgp
, __func__
);
3223 bgp_route_map_add (const char *rmap_name
)
3225 if (route_map_mark_updated(rmap_name
, 0) == 0)
3226 bgp_route_map_mark_update(rmap_name
);
3228 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3232 bgp_route_map_delete (const char *rmap_name
)
3234 if (route_map_mark_updated(rmap_name
, 1) == 0)
3235 bgp_route_map_mark_update(rmap_name
);
3237 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
3241 bgp_route_map_event (route_map_event_t event
, const char *rmap_name
)
3243 if (route_map_mark_updated(rmap_name
, 0) == 0)
3244 bgp_route_map_mark_update(rmap_name
);
3246 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
3252 "match peer <A.B.C.D|X:X::X:X>",
3254 "Match peer address\n"
3255 "IP address of peer\n"
3256 "IPv6 address of peer\n")
3259 return bgp_route_match_add (vty
, "peer", argv
[idx_ip
]->arg
,
3260 RMAP_EVENT_MATCH_ADDED
);
3263 DEFUN (match_peer_local
,
3264 match_peer_local_cmd
,
3267 "Match peer address\n"
3268 "Static or Redistributed routes\n")
3270 return bgp_route_match_add (vty
, "peer", "local",
3271 RMAP_EVENT_MATCH_DELETED
);
3274 DEFUN (no_match_peer
,
3276 "no match peer [<local|A.B.C.D|X:X::X:X>]",
3279 "Match peer address\n"
3280 "Static or Redistributed routes\n"
3281 "IP address of peer\n"
3282 "IPv6 address of peer\n")
3286 if (argc
<= idx_peer
)
3287 return bgp_route_match_delete (vty
, "peer", NULL
,
3288 RMAP_EVENT_MATCH_DELETED
);
3289 return bgp_route_match_delete (vty
, "peer", argv
[idx_peer
]->arg
,
3290 RMAP_EVENT_MATCH_DELETED
);
3294 /* match probability */
3295 DEFUN (match_probability
,
3296 match_probability_cmd
,
3297 "match probability (0-100)",
3299 "Match portion of routes defined by percentage value\n"
3300 "Percentage of routes\n")
3303 return bgp_route_match_add (vty
, "probability", argv
[idx_number
]->arg
,
3304 RMAP_EVENT_MATCH_ADDED
);
3308 DEFUN (no_match_probability
,
3309 no_match_probability_cmd
,
3310 "no match probability [(1-99)]",
3313 "Match portion of routes defined by percentage value\n"
3314 "Percentage of routes\n")
3317 if (argc
<= idx_number
)
3318 return bgp_route_match_delete (vty
, "probability", NULL
,
3319 RMAP_EVENT_MATCH_DELETED
);
3320 return bgp_route_match_delete (vty
, "probability", argv
[idx_number
]->arg
,
3321 RMAP_EVENT_MATCH_DELETED
);
3325 DEFUN (match_ip_route_source
,
3326 match_ip_route_source_cmd
,
3327 "match ip route-source <(1-199)|(1300-2699)|WORD>",
3330 "Match advertising source address of route\n"
3331 "IP access-list number\n"
3332 "IP access-list number (expanded range)\n"
3333 "IP standard access-list name\n")
3336 return bgp_route_match_add (vty
, "ip route-source", argv
[idx_acl
]->arg
,
3337 RMAP_EVENT_FILTER_ADDED
);
3341 DEFUN (no_match_ip_route_source
,
3342 no_match_ip_route_source_cmd
,
3343 "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
3347 "Match advertising source address of route\n"
3348 "IP access-list number\n"
3349 "IP access-list number (expanded range)\n"
3350 "IP standard access-list name\n")
3353 if (argc
<= idx_number
)
3354 return bgp_route_match_delete (vty
, "ip route-source",
3355 NULL
, RMAP_EVENT_FILTER_DELETED
);
3356 return bgp_route_match_delete (vty
, "ip route-source",
3357 argv
[idx_number
]->arg
, RMAP_EVENT_FILTER_DELETED
);
3361 DEFUN (match_ip_route_source_prefix_list
,
3362 match_ip_route_source_prefix_list_cmd
,
3363 "match ip route-source prefix-list WORD",
3366 "Match advertising source address of route\n"
3367 "Match entries of prefix-lists\n"
3368 "IP prefix-list name\n")
3371 return bgp_route_match_add (vty
, "ip route-source prefix-list",
3372 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3376 DEFUN (no_match_ip_route_source_prefix_list
,
3377 no_match_ip_route_source_prefix_list_cmd
,
3378 "no match ip route-source prefix-list [WORD]",
3382 "Match advertising source address of route\n"
3383 "Match entries of prefix-lists\n"
3384 "IP prefix-list name\n")
3387 if (argc
<= idx_word
)
3388 return bgp_route_match_delete (vty
, "ip route-source prefix-list",
3389 NULL
, RMAP_EVENT_PLIST_DELETED
);
3390 return bgp_route_match_delete (vty
, "ip route-source prefix-list",
3391 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_DELETED
);
3395 DEFUN (match_local_pref
,
3396 match_local_pref_cmd
,
3397 "match local-preference (0-4294967295)",
3399 "Match local-preference of route\n"
3403 return bgp_route_match_add (vty
, "local-preference", argv
[idx_number
]->arg
,
3404 RMAP_EVENT_MATCH_ADDED
);
3408 DEFUN (no_match_local_pref
,
3409 no_match_local_pref_cmd
,
3410 "no match local-preference [(0-4294967295)]",
3413 "Match local preference of route\n"
3414 "Local preference value\n")
3416 int idx_localpref
= 3;
3417 if (argc
<= idx_localpref
)
3418 return bgp_route_match_delete (vty
, "local-preference",
3419 NULL
, RMAP_EVENT_MATCH_DELETED
);
3420 return bgp_route_match_delete (vty
, "local-preference",
3421 argv
[idx_localpref
]->arg
,
3422 RMAP_EVENT_MATCH_DELETED
);
3426 DEFUN (match_community
,
3427 match_community_cmd
,
3428 "match community <(1-99)|(100-500)|WORD> [exact-match]",
3430 "Match BGP community list\n"
3431 "Community-list number (standard)\n"
3432 "Community-list number (expanded)\n"
3433 "Community-list name\n"
3434 "Do exact matching of communities\n")
3436 int idx_comm_list
= 2;
3442 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3443 strlen (argv
[idx_comm_list
]->arg
) +
3444 strlen ("exact-match") + 2);
3446 sprintf (argstr
, "%s exact-match", argv
[idx_comm_list
]->arg
);
3449 argstr
= argv
[idx_comm_list
]->arg
;
3451 ret
= bgp_route_match_add (vty
, "community", argstr
,
3452 RMAP_EVENT_CLIST_ADDED
);
3454 if (argstr
!= argv
[idx_comm_list
]->arg
)
3455 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3460 DEFUN (no_match_community
,
3461 no_match_community_cmd
,
3462 "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
3465 "Match BGP community list\n"
3466 "Community-list number (standard)\n"
3467 "Community-list number (expanded)\n"
3468 "Community-list name\n"
3469 "Do exact matching of communities\n")
3471 return bgp_route_match_delete (vty
, "community", NULL
,
3472 RMAP_EVENT_CLIST_DELETED
);
3475 DEFUN (match_lcommunity
,
3476 match_lcommunity_cmd
,
3477 "match large-community <(1-99)|(100-500)|WORD>",
3479 "Match BGP large community list\n"
3480 "Large Community-list number (standard)\n"
3481 "Large Community-list number (expanded)\n"
3482 "Large Community-list name\n")
3484 return bgp_route_match_add (vty
, "large-community", argv
[2]->arg
,
3485 RMAP_EVENT_LLIST_ADDED
);
3488 DEFUN (no_match_lcommunity
,
3489 no_match_lcommunity_cmd
,
3490 "no match large-community [<(1-99)|(100-500)|WORD>]",
3493 "Match BGP large community list\n"
3494 "Large Community-list number (standard)\n"
3495 "Large Community-list number (expanded)\n"
3496 "Large Community-list name\n")
3498 return bgp_route_match_delete (vty
, "large-community", NULL
,
3499 RMAP_EVENT_LLIST_DELETED
);
3502 DEFUN (match_ecommunity
,
3503 match_ecommunity_cmd
,
3504 "match extcommunity <(1-99)|(100-500)|WORD>",
3506 "Match BGP/VPN extended community list\n"
3507 "Extended community-list number (standard)\n"
3508 "Extended community-list number (expanded)\n"
3509 "Extended community-list name\n")
3511 int idx_comm_list
= 2;
3512 return bgp_route_match_add (vty
, "extcommunity", argv
[idx_comm_list
]->arg
,
3513 RMAP_EVENT_ECLIST_ADDED
);
3517 DEFUN (no_match_ecommunity
,
3518 no_match_ecommunity_cmd
,
3519 "no match extcommunity [<(1-99)|(100-500)|WORD>]",
3522 "Match BGP/VPN extended community list\n"
3523 "Extended community-list number (standard)\n"
3524 "Extended community-list number (expanded)\n"
3525 "Extended community-list name\n")
3527 return bgp_route_match_delete (vty
, "extcommunity", NULL
,
3528 RMAP_EVENT_ECLIST_DELETED
);
3532 DEFUN (match_aspath
,
3534 "match as-path WORD",
3536 "Match BGP AS path list\n"
3537 "AS path access-list name\n")
3540 return bgp_route_match_add (vty
, "as-path", argv
[idx_word
]->arg
,
3541 RMAP_EVENT_ASLIST_ADDED
);
3545 DEFUN (no_match_aspath
,
3546 no_match_aspath_cmd
,
3547 "no match as-path [WORD]",
3550 "Match BGP AS path list\n"
3551 "AS path access-list name\n")
3553 return bgp_route_match_delete (vty
, "as-path", NULL
,
3554 RMAP_EVENT_ASLIST_DELETED
);
3558 DEFUN (match_origin
,
3560 "match origin <egp|igp|incomplete>",
3565 "unknown heritage\n")
3568 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
3569 return bgp_route_match_add (vty
, "origin", "igp",
3570 RMAP_EVENT_MATCH_ADDED
);
3571 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
3572 return bgp_route_match_add (vty
, "origin", "egp",
3573 RMAP_EVENT_MATCH_ADDED
);
3574 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3575 return bgp_route_match_add (vty
, "origin", "incomplete",
3576 RMAP_EVENT_MATCH_ADDED
);
3578 vty_outln (vty
, "%% Invalid match origin type");
3579 return CMD_WARNING_CONFIG_FAILED
;
3583 DEFUN (no_match_origin
,
3584 no_match_origin_cmd
,
3585 "no match origin [<egp|igp|incomplete>]",
3591 "unknown heritage\n")
3593 return bgp_route_match_delete (vty
, "origin", NULL
,
3594 RMAP_EVENT_MATCH_DELETED
);
3597 DEFUN (set_ip_nexthop_peer
,
3598 set_ip_nexthop_peer_cmd
,
3599 "set ip next-hop peer-address",
3602 "Next hop address\n"
3603 "Use peer address (for BGP only)\n")
3605 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3606 "ip next-hop", "peer-address");
3609 DEFUN (set_ip_nexthop_unchanged
,
3610 set_ip_nexthop_unchanged_cmd
,
3611 "set ip next-hop unchanged",
3614 "Next hop address\n"
3615 "Don't modify existing Next hop address\n")
3617 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3618 "ip next-hop", "unchanged");
3622 DEFUN (set_local_pref
,
3624 "set local-preference (0-4294967295)",
3626 "BGP local preference path attribute\n"
3627 "Preference value\n")
3630 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3631 "local-preference", argv
[idx_number
]->arg
);
3635 DEFUN (no_set_local_pref
,
3636 no_set_local_pref_cmd
,
3637 "no set local-preference [(0-4294967295)]",
3640 "BGP local preference path attribute\n"
3641 "Preference value\n")
3643 int idx_localpref
= 3;
3644 if (argc
<= idx_localpref
)
3645 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3646 "local-preference", NULL
);
3647 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3648 "local-preference", argv
[idx_localpref
]->arg
);
3654 "set weight (0-4294967295)",
3656 "BGP weight for routing table\n"
3660 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "weight",
3661 argv
[idx_number
]->arg
);
3665 DEFUN (no_set_weight
,
3667 "no set weight [(0-4294967295)]",
3670 "BGP weight for routing table\n"
3674 if (argc
<= idx_weight
)
3675 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3677 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
), "weight",
3678 argv
[idx_weight
]->arg
);
3681 DEFUN (set_label_index
,
3682 set_label_index_cmd
,
3683 "set label-index (0-1048560)",
3685 "Label index to associate with the prefix\n"
3686 "Label index value\n")
3689 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "label-index",
3690 argv
[idx_number
]->arg
);
3693 DEFUN (no_set_label_index
,
3694 no_set_label_index_cmd
,
3695 "no set label-index [(0-1048560)]",
3698 "Label index to associate with the prefix\n"
3699 "Label index value\n")
3701 int idx_label_index
= 3;
3702 if (argc
<= idx_label_index
)
3703 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3704 "label-index", NULL
);
3705 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
), "label-index",
3706 argv
[idx_label_index
]->arg
);
3709 DEFUN (set_aspath_prepend_asn
,
3710 set_aspath_prepend_asn_cmd
,
3711 "set as-path prepend (1-4294967295)...",
3713 "Transform BGP AS_PATH attribute\n"
3714 "Prepend to the as-path\n"
3721 str
= argv_concat (argv
, argc
, idx_asn
);
3722 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3723 "as-path prepend", str
);
3724 XFREE (MTYPE_TMP
, str
);
3729 DEFUN (set_aspath_prepend_lastas
,
3730 set_aspath_prepend_lastas_cmd
,
3731 "set as-path prepend last-as (1-10)",
3733 "Transform BGP AS_PATH attribute\n"
3734 "Prepend to the as-path\n"
3735 "Use the peer's AS-number\n"
3736 "Number of times to insert\n")
3738 return set_aspath_prepend_asn (self
, vty
, argc
, argv
);
3741 DEFUN (no_set_aspath_prepend
,
3742 no_set_aspath_prepend_cmd
,
3743 "no set as-path prepend [(1-4294967295)]",
3746 "Transform BGP AS_PATH attribute\n"
3747 "Prepend to the as-path\n"
3754 str
= argv_concat (argv
, argc
, idx_asn
);
3755 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3756 "as-path prepend", str
);
3757 XFREE (MTYPE_TMP
, str
);
3762 DEFUN (set_aspath_exclude
,
3763 set_aspath_exclude_cmd
,
3764 "set as-path exclude (1-4294967295)...",
3766 "Transform BGP AS-path attribute\n"
3767 "Exclude from the as-path\n"
3774 str
= argv_concat (argv
, argc
, idx_asn
);
3775 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3776 "as-path exclude", str
);
3777 XFREE (MTYPE_TMP
, str
);
3781 DEFUN (no_set_aspath_exclude
,
3782 no_set_aspath_exclude_cmd
,
3783 "no set as-path exclude (1-4294967295)...",
3786 "Transform BGP AS_PATH attribute\n"
3787 "Exclude from the as-path\n"
3794 str
= argv_concat (argv
, argc
, idx_asn
);
3795 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3796 "as-path exclude", str
);
3797 XFREE (MTYPE_TMP
, str
);
3802 DEFUN (set_community
,
3804 "set community AA:NN...",
3806 "BGP community attribute\n"
3814 struct community
*com
= NULL
;
3819 b
= buffer_new (1024);
3821 for (i
= idx_aa_nn
; i
< argc
; i
++)
3823 if (strncmp (argv
[i
]->arg
, "additive", strlen (argv
[i
]->arg
)) == 0)
3830 buffer_putc (b
, ' ');
3834 if (strncmp (argv
[i
]->arg
, "internet", strlen (argv
[i
]->arg
)) == 0)
3836 buffer_putstr (b
, "internet");
3839 if (strncmp (argv
[i
]->arg
, "local-AS", strlen (argv
[i
]->arg
)) == 0)
3841 buffer_putstr (b
, "local-AS");
3844 if (strncmp (argv
[i
]->arg
, "no-a", strlen ("no-a")) == 0
3845 && strncmp (argv
[i
]->arg
, "no-advertise", strlen (argv
[i
]->arg
)) == 0)
3847 buffer_putstr (b
, "no-advertise");
3850 if (strncmp (argv
[i
]->arg
, "no-e", strlen ("no-e"))== 0
3851 && strncmp (argv
[i
]->arg
, "no-export", strlen (argv
[i
]->arg
)) == 0)
3853 buffer_putstr (b
, "no-export");
3856 buffer_putstr (b
, argv
[i
]->arg
);
3858 buffer_putc (b
, '\0');
3860 /* Fetch result string then compile it to communities attribute. */
3861 str
= buffer_getstr (b
);
3866 com
= community_str2com (str
);
3867 XFREE (MTYPE_TMP
, str
);
3870 /* Can't compile user input into communities attribute. */
3873 vty_outln (vty
, "%% Malformed communities attribute");
3874 return CMD_WARNING_CONFIG_FAILED
;
3877 /* Set communites attribute string. */
3878 str
= community_str (com
);
3882 argstr
= XCALLOC (MTYPE_TMP
, strlen (str
) + strlen (" additive") + 1);
3883 strcpy (argstr
, str
);
3884 strcpy (argstr
+ strlen (str
), " additive");
3885 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3886 "community", argstr
);
3887 XFREE (MTYPE_TMP
, argstr
);
3890 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3893 community_free (com
);
3898 DEFUN (set_community_none
,
3899 set_community_none_cmd
,
3900 "set community none",
3902 "BGP community attribute\n"
3903 "No community attribute\n")
3905 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "community",
3909 DEFUN (no_set_community
,
3910 no_set_community_cmd
,
3911 "no set community AA:NN...",
3914 "BGP community attribute\n"
3917 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3923 DEFUN (set_community_delete
,
3924 set_community_delete_cmd
,
3925 "set comm-list <(1-99)|(100-500)|WORD> delete",
3927 "set BGP community list (for deletion)\n"
3928 "Community-list number (standard)\n"
3929 "Community-list number (expanded)\n"
3930 "Community-list name\n"
3931 "Delete matching communities\n")
3933 int idx_comm_list
= 2;
3936 str
= XCALLOC (MTYPE_TMP
, strlen (argv
[idx_comm_list
]->arg
) + strlen (" delete") + 1);
3937 strcpy (str
, argv
[idx_comm_list
]->arg
);
3938 strcpy (str
+ strlen (argv
[idx_comm_list
]->arg
), " delete");
3940 generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "comm-list", str
);
3942 XFREE (MTYPE_TMP
, str
);
3946 DEFUN (no_set_community_delete
,
3947 no_set_community_delete_cmd
,
3948 "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
3951 "set BGP community list (for deletion)\n"
3952 "Community-list number (standard)\n"
3953 "Community-list number (expanded)\n"
3954 "Community-list name\n"
3955 "Delete matching communities\n")
3957 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3961 DEFUN (set_lcommunity
,
3963 "set large-community AA:BB:CC...",
3965 "BGP large community attribute\n"
3966 "Large Community number in aa:bb:cc format or additive\n")
3971 str
= argv_concat (argv
, argc
, 2);
3972 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "large-community", str
);
3973 XFREE (MTYPE_TMP
, str
);
3978 DEFUN (set_lcommunity_none
,
3979 set_lcommunity_none_cmd
,
3980 "set large-community none",
3982 "BGP large community attribute\n"
3983 "No large community attribute\n")
3985 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3986 "large-community", "none");
3989 DEFUN (no_set_lcommunity
,
3990 no_set_lcommunity_cmd
,
3991 "no set large-community none",
3994 "BGP large community attribute\n"
3995 "No community attribute\n")
3997 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3998 "large-community", NULL
);
4001 DEFUN (no_set_lcommunity1
,
4002 no_set_lcommunity1_cmd
,
4003 "no set large-community AA:BB:CC...",
4006 "BGP large community attribute\n"
4007 "Large community in AA:BB:CC... format or additive\n")
4009 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4010 "large-community", NULL
);
4013 DEFUN (set_lcommunity_delete
,
4014 set_lcommunity_delete_cmd
,
4015 "set large-comm-list <(1-99)|(100-500)|WORD> delete",
4017 "set BGP large community list (for deletion)\n"
4018 "Large Community-list number (standard)\n"
4019 "Large Communitly-list number (expanded)\n"
4020 "Large Community-list name\n"
4021 "Delete matching large communities\n")
4025 str
= XCALLOC (MTYPE_TMP
, strlen (argv
[2]->arg
) + strlen (" delete") + 1);
4026 strcpy (str
, argv
[2]->arg
);
4027 strcpy (str
+ strlen (argv
[2]->arg
), " delete");
4029 generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4030 "large-comm-list", str
);
4032 XFREE (MTYPE_TMP
, str
);
4036 DEFUN (no_set_lcommunity_delete
,
4037 no_set_lcommunity_delete_cmd
,
4038 "no set large-comm-list <(1-99)|(100-500)|WORD> [delete]",
4041 "set BGP large community list (for deletion)\n"
4042 "Large Community-list number (standard)\n"
4043 "Large Communitly-list number (expanded)\n"
4044 "Large Community-list name\n"
4045 "Delete matching large communities\n")
4047 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4048 "large-comm-list", NULL
);
4051 DEFUN (set_ecommunity_rt
,
4052 set_ecommunity_rt_cmd
,
4053 "set extcommunity rt ASN:nn_or_IP-address:nn...",
4055 "BGP extended community attribute\n"
4056 "Route Target extended community\n"
4057 "VPN extended community\n")
4063 str
= argv_concat (argv
, argc
, idx_asn_nn
);
4064 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4065 "extcommunity rt", str
);
4066 XFREE (MTYPE_TMP
, str
);
4071 DEFUN (no_set_ecommunity_rt
,
4072 no_set_ecommunity_rt_cmd
,
4073 "no set extcommunity rt ASN:nn_or_IP-address:nn...",
4076 "BGP extended community attribute\n"
4077 "Route Target extended community\n"
4078 "VPN extended community\n")
4080 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4081 "extcommunity rt", NULL
);
4085 DEFUN (set_ecommunity_soo
,
4086 set_ecommunity_soo_cmd
,
4087 "set extcommunity soo ASN:nn_or_IP-address:nn...",
4089 "BGP extended community attribute\n"
4090 "Site-of-Origin extended community\n"
4091 "VPN extended community\n")
4097 str
= argv_concat (argv
, argc
, idx_asn_nn
);
4098 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4099 "extcommunity soo", str
);
4100 XFREE (MTYPE_TMP
, str
);
4105 DEFUN (no_set_ecommunity_soo
,
4106 no_set_ecommunity_soo_cmd
,
4107 "no set extcommunity soo ASN:nn_or_IP-address:nn...",
4110 "BGP extended community attribute\n"
4111 "Site-of-Origin extended community\n"
4112 "VPN extended community\n")
4114 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4115 "extcommunity soo", NULL
);
4121 "set origin <egp|igp|incomplete>",
4126 "unknown heritage\n")
4129 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
4130 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4132 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
4133 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4135 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
4136 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4139 vty_outln (vty
, "%% Invalid set origin type");
4140 return CMD_WARNING_CONFIG_FAILED
;
4144 DEFUN (no_set_origin
,
4146 "no set origin [<egp|igp|incomplete>]",
4152 "unknown heritage\n")
4154 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
4159 DEFUN (set_atomic_aggregate
,
4160 set_atomic_aggregate_cmd
,
4161 "set atomic-aggregate",
4163 "BGP atomic aggregate attribute\n" )
4165 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4166 "atomic-aggregate", NULL
);
4169 DEFUN (no_set_atomic_aggregate
,
4170 no_set_atomic_aggregate_cmd
,
4171 "no set atomic-aggregate",
4174 "BGP atomic aggregate attribute\n" )
4176 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4177 "atomic-aggregate", NULL
);
4180 DEFUN (set_aggregator_as
,
4181 set_aggregator_as_cmd
,
4182 "set aggregator as (1-4294967295) A.B.C.D",
4184 "BGP aggregator attribute\n"
4185 "AS number of aggregator\n"
4187 "IP address of aggregator\n")
4192 struct in_addr address
;
4195 ret
= inet_aton (argv
[idx_ipv4
]->arg
, &address
);
4198 vty_outln (vty
, "Aggregator IP address is invalid");
4199 return CMD_WARNING_CONFIG_FAILED
;
4202 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
4203 strlen (argv
[idx_number
]->arg
) + strlen (argv
[idx_ipv4
]->arg
) + 2);
4205 sprintf (argstr
, "%s %s", argv
[idx_number
]->arg
, argv
[idx_ipv4
]->arg
);
4207 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4208 "aggregator as", argstr
);
4210 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4216 DEFUN (no_set_aggregator_as
,
4217 no_set_aggregator_as_cmd
,
4218 "no set aggregator as [(1-4294967295) A.B.C.D]",
4221 "BGP aggregator attribute\n"
4222 "AS number of aggregator\n"
4224 "IP address of aggregator\n")
4229 struct in_addr address
;
4232 if (argc
<= idx_asn
)
4233 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4234 "aggregator as", NULL
);
4236 ret
= inet_aton (argv
[idx_ip
]->arg
, &address
);
4239 vty_outln (vty
, "Aggregator IP address is invalid");
4240 return CMD_WARNING_CONFIG_FAILED
;
4243 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
4244 strlen (argv
[idx_asn
]->arg
) + strlen (argv
[idx_ip
]->arg
) + 2);
4246 sprintf (argstr
, "%s %s", argv
[idx_asn
]->arg
, argv
[idx_ip
]->arg
);
4248 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4249 "aggregator as", argstr
);
4251 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
4256 DEFUN (match_ipv6_next_hop
,
4257 match_ipv6_next_hop_cmd
,
4258 "match ipv6 next-hop X:X::X:X",
4261 "Match IPv6 next-hop address of route\n"
4262 "IPv6 address of next hop\n")
4265 return bgp_route_match_add (vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4266 RMAP_EVENT_MATCH_ADDED
);
4269 DEFUN (no_match_ipv6_next_hop
,
4270 no_match_ipv6_next_hop_cmd
,
4271 "no match ipv6 next-hop X:X::X:X",
4275 "Match IPv6 next-hop address of route\n"
4276 "IPv6 address of next hop\n")
4279 return bgp_route_match_delete (vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
4280 RMAP_EVENT_MATCH_DELETED
);
4284 DEFUN (set_ipv6_nexthop_peer
,
4285 set_ipv6_nexthop_peer_cmd
,
4286 "set ipv6 next-hop peer-address",
4289 "Next hop address\n"
4290 "Use peer address (for BGP only)\n")
4292 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4293 "ipv6 next-hop peer-address", NULL
);
4296 DEFUN (no_set_ipv6_nexthop_peer
,
4297 no_set_ipv6_nexthop_peer_cmd
,
4298 "no set ipv6 next-hop peer-address",
4302 "IPv6 next-hop address\n"
4303 "Use peer address (for BGP only)\n")
4305 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4306 "ipv6 next-hop peer-address", NULL
);
4309 DEFUN (set_ipv6_nexthop_prefer_global
,
4310 set_ipv6_nexthop_prefer_global_cmd
,
4311 "set ipv6 next-hop prefer-global",
4314 "IPv6 next-hop address\n"
4315 "Prefer global over link-local if both exist\n")
4317 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4318 "ipv6 next-hop prefer-global", NULL
);;
4321 DEFUN (no_set_ipv6_nexthop_prefer_global
,
4322 no_set_ipv6_nexthop_prefer_global_cmd
,
4323 "no set ipv6 next-hop prefer-global",
4327 "IPv6 next-hop address\n"
4328 "Prefer global over link-local if both exist\n")
4330 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4331 "ipv6 next-hop prefer-global", NULL
);
4334 DEFUN (set_ipv6_nexthop_global
,
4335 set_ipv6_nexthop_global_cmd
,
4336 "set ipv6 next-hop global X:X::X:X",
4339 "IPv6 next-hop address\n"
4340 "IPv6 global address\n"
4341 "IPv6 address of next hop\n")
4344 struct in6_addr addr
;
4347 ret
= inet_pton (AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
4350 vty_outln (vty
, "%% Malformed nexthop address");
4351 return CMD_WARNING_CONFIG_FAILED
;
4353 if (IN6_IS_ADDR_UNSPECIFIED(&addr
) ||
4354 IN6_IS_ADDR_LOOPBACK(&addr
) ||
4355 IN6_IS_ADDR_MULTICAST(&addr
) ||
4356 IN6_IS_ADDR_LINKLOCAL(&addr
))
4358 vty_outln (vty
, "%% Invalid global nexthop address");
4359 return CMD_WARNING_CONFIG_FAILED
;
4362 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4363 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4367 DEFUN (no_set_ipv6_nexthop_global
,
4368 no_set_ipv6_nexthop_global_cmd
,
4369 "no set ipv6 next-hop global X:X::X:X",
4373 "IPv6 next-hop address\n"
4374 "IPv6 global address\n"
4375 "IPv6 address of next hop\n")
4378 if (argc
<= idx_ipv6
)
4379 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4380 "ipv6 next-hop global", NULL
);
4381 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4382 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
4385 #ifdef KEEP_OLD_VPN_COMMANDS
4386 DEFUN (set_vpn_nexthop
,
4387 set_vpn_nexthop_cmd
,
4388 "set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
4390 "VPNv4 information\n"
4391 "VPN next-hop address\n"
4392 "IP address of next hop\n"
4393 "VPNv6 information\n"
4394 "VPN next-hop address\n"
4395 "IPv6 address of next hop\n")
4401 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
4404 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4405 "ip vpn next-hop", argv
[idx_ip
]->arg
);
4407 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4408 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4413 DEFUN (no_set_vpn_nexthop
,
4414 no_set_vpn_nexthop_cmd
,
4415 "no set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
4418 "VPNv4 information\n"
4419 "VPN next-hop address\n"
4420 "IP address of next hop\n"
4421 "VPNv6 information\n"
4422 "VPN next-hop address\n"
4423 "IPv6 address of next hop\n")
4433 arg
= argv
[idx_ip
]->arg
;
4434 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
4437 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4438 "ip vpn next-hop", arg
);
4440 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4441 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4445 #endif /* KEEP_OLD_VPN_COMMANDS */
4447 DEFUN (set_ipx_vpn_nexthop
,
4448 set_ipx_vpn_nexthop_cmd
,
4449 "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
4451 "IPv4 information\n"
4452 "IPv6 information\n"
4454 "VPN next-hop address\n"
4455 "IP address of next hop\n"
4456 "IPv6 address of next hop\n")
4462 if (argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
))
4465 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4466 "ip vpn next-hop", argv
[idx_ip
]->arg
);
4468 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4469 "ipv6 vpn next-hop", argv
[idx_ip
]->arg
);
4474 DEFUN (no_set_ipx_vpn_nexthop
,
4475 no_set_ipx_vpn_nexthop_cmd
,
4476 "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
4479 "IPv4 information\n"
4480 "IPv6 information\n"
4482 "VPN next-hop address\n"
4483 "IP address of next hop\n"
4484 "IPv6 address of next hop\n")
4494 arg
= argv
[idx_ip
]->arg
;
4495 if (argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
))
4498 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4499 "ip vpn next-hop", arg
);
4501 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4502 "ipv6 vpn next-hop", arg
);
4507 DEFUN (set_originator_id
,
4508 set_originator_id_cmd
,
4509 "set originator-id A.B.C.D",
4511 "BGP originator ID attribute\n"
4512 "IP address of originator\n")
4515 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
4516 "originator-id", argv
[idx_ipv4
]->arg
);
4520 DEFUN (no_set_originator_id
,
4521 no_set_originator_id_cmd
,
4522 "no set originator-id [A.B.C.D]",
4525 "BGP originator ID attribute\n"
4526 "IP address of originator\n")
4529 char *arg
= argv_find (argv
, argc
, "A.B.C.D", &idx
) ? argv
[idx
]->arg
: NULL
;
4531 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
4532 "originator-id", arg
);
4536 /* Initialization of route map. */
4538 bgp_route_map_init (void)
4542 route_map_add_hook (bgp_route_map_add
);
4543 route_map_delete_hook (bgp_route_map_delete
);
4544 route_map_event_hook (bgp_route_map_event
);
4546 route_map_match_interface_hook (generic_match_add
);
4547 route_map_no_match_interface_hook (generic_match_delete
);
4549 route_map_match_ip_address_hook (generic_match_add
);
4550 route_map_no_match_ip_address_hook (generic_match_delete
);
4552 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
4553 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
4555 route_map_match_ip_next_hop_hook (generic_match_add
);
4556 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
4558 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
4559 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
4561 route_map_match_ipv6_address_hook (generic_match_add
);
4562 route_map_no_match_ipv6_address_hook (generic_match_delete
);
4564 route_map_match_ipv6_address_prefix_list_hook (generic_match_add
);
4565 route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete
);
4567 route_map_match_metric_hook (generic_match_add
);
4568 route_map_no_match_metric_hook (generic_match_delete
);
4570 route_map_match_tag_hook (generic_match_add
);
4571 route_map_no_match_tag_hook (generic_match_delete
);
4573 route_map_set_ip_nexthop_hook (generic_set_add
);
4574 route_map_no_set_ip_nexthop_hook (generic_set_delete
);
4576 route_map_set_ipv6_nexthop_local_hook (generic_set_add
);
4577 route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete
);
4579 route_map_set_metric_hook (generic_set_add
);
4580 route_map_no_set_metric_hook (generic_set_delete
);
4582 route_map_set_tag_hook (generic_set_add
);
4583 route_map_no_set_tag_hook (generic_set_delete
);
4585 route_map_install_match (&route_match_peer_cmd
);
4586 route_map_install_match (&route_match_local_pref_cmd
);
4587 route_map_install_match (&route_match_ip_address_cmd
);
4588 route_map_install_match (&route_match_ip_next_hop_cmd
);
4589 route_map_install_match (&route_match_ip_route_source_cmd
);
4590 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
4591 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
4592 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd
);
4593 route_map_install_match (&route_match_aspath_cmd
);
4594 route_map_install_match (&route_match_community_cmd
);
4595 route_map_install_match (&route_match_lcommunity_cmd
);
4596 route_map_install_match (&route_match_ecommunity_cmd
);
4597 route_map_install_match (&route_match_local_pref_cmd
);
4598 route_map_install_match (&route_match_metric_cmd
);
4599 route_map_install_match (&route_match_origin_cmd
);
4600 route_map_install_match (&route_match_probability_cmd
);
4601 route_map_install_match (&route_match_interface_cmd
);
4602 route_map_install_match (&route_match_tag_cmd
);
4604 route_map_install_set (&route_set_ip_nexthop_cmd
);
4605 route_map_install_set (&route_set_local_pref_cmd
);
4606 route_map_install_set (&route_set_weight_cmd
);
4607 route_map_install_set (&route_set_label_index_cmd
);
4608 route_map_install_set (&route_set_metric_cmd
);
4609 route_map_install_set (&route_set_aspath_prepend_cmd
);
4610 route_map_install_set (&route_set_aspath_exclude_cmd
);
4611 route_map_install_set (&route_set_origin_cmd
);
4612 route_map_install_set (&route_set_atomic_aggregate_cmd
);
4613 route_map_install_set (&route_set_aggregator_as_cmd
);
4614 route_map_install_set (&route_set_community_cmd
);
4615 route_map_install_set (&route_set_community_delete_cmd
);
4616 route_map_install_set (&route_set_lcommunity_cmd
);
4617 route_map_install_set (&route_set_lcommunity_delete_cmd
);
4618 route_map_install_set (&route_set_vpnv4_nexthop_cmd
);
4619 route_map_install_set (&route_set_vpnv6_nexthop_cmd
);
4620 route_map_install_set (&route_set_originator_id_cmd
);
4621 route_map_install_set (&route_set_ecommunity_rt_cmd
);
4622 route_map_install_set (&route_set_ecommunity_soo_cmd
);
4623 route_map_install_set (&route_set_tag_cmd
);
4624 route_map_install_set (&route_set_label_index_cmd
);
4626 install_element (RMAP_NODE
, &match_peer_cmd
);
4627 install_element (RMAP_NODE
, &match_peer_local_cmd
);
4628 install_element (RMAP_NODE
, &no_match_peer_cmd
);
4629 install_element (RMAP_NODE
, &match_ip_route_source_cmd
);
4630 install_element (RMAP_NODE
, &no_match_ip_route_source_cmd
);
4631 install_element (RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
4632 install_element (RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
4634 install_element (RMAP_NODE
, &match_aspath_cmd
);
4635 install_element (RMAP_NODE
, &no_match_aspath_cmd
);
4636 install_element (RMAP_NODE
, &match_local_pref_cmd
);
4637 install_element (RMAP_NODE
, &no_match_local_pref_cmd
);
4638 install_element (RMAP_NODE
, &match_community_cmd
);
4639 install_element (RMAP_NODE
, &no_match_community_cmd
);
4640 install_element (RMAP_NODE
, &match_lcommunity_cmd
);
4641 install_element (RMAP_NODE
, &no_match_lcommunity_cmd
);
4642 install_element (RMAP_NODE
, &match_ecommunity_cmd
);
4643 install_element (RMAP_NODE
, &no_match_ecommunity_cmd
);
4644 install_element (RMAP_NODE
, &match_origin_cmd
);
4645 install_element (RMAP_NODE
, &no_match_origin_cmd
);
4646 install_element (RMAP_NODE
, &match_probability_cmd
);
4647 install_element (RMAP_NODE
, &no_match_probability_cmd
);
4649 install_element (RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
4650 install_element (RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
4651 install_element (RMAP_NODE
, &set_local_pref_cmd
);
4652 install_element (RMAP_NODE
, &no_set_local_pref_cmd
);
4653 install_element (RMAP_NODE
, &set_weight_cmd
);
4654 install_element (RMAP_NODE
, &set_label_index_cmd
);
4655 install_element (RMAP_NODE
, &no_set_weight_cmd
);
4656 install_element (RMAP_NODE
, &no_set_label_index_cmd
);
4657 install_element (RMAP_NODE
, &set_aspath_prepend_asn_cmd
);
4658 install_element (RMAP_NODE
, &set_aspath_prepend_lastas_cmd
);
4659 install_element (RMAP_NODE
, &set_aspath_exclude_cmd
);
4660 install_element (RMAP_NODE
, &no_set_aspath_prepend_cmd
);
4661 install_element (RMAP_NODE
, &no_set_aspath_exclude_cmd
);
4662 install_element (RMAP_NODE
, &set_origin_cmd
);
4663 install_element (RMAP_NODE
, &no_set_origin_cmd
);
4664 install_element (RMAP_NODE
, &set_atomic_aggregate_cmd
);
4665 install_element (RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
4666 install_element (RMAP_NODE
, &set_aggregator_as_cmd
);
4667 install_element (RMAP_NODE
, &no_set_aggregator_as_cmd
);
4668 install_element (RMAP_NODE
, &set_community_cmd
);
4669 install_element (RMAP_NODE
, &set_community_none_cmd
);
4670 install_element (RMAP_NODE
, &no_set_community_cmd
);
4671 install_element (RMAP_NODE
, &set_community_delete_cmd
);
4672 install_element (RMAP_NODE
, &no_set_community_delete_cmd
);
4673 install_element (RMAP_NODE
, &set_lcommunity_cmd
);
4674 install_element (RMAP_NODE
, &set_lcommunity_none_cmd
);
4675 install_element (RMAP_NODE
, &no_set_lcommunity_cmd
);
4676 install_element (RMAP_NODE
, &no_set_lcommunity1_cmd
);
4677 install_element (RMAP_NODE
, &set_lcommunity_delete_cmd
);
4678 install_element (RMAP_NODE
, &no_set_lcommunity_delete_cmd
);
4679 install_element (RMAP_NODE
, &set_ecommunity_rt_cmd
);
4680 install_element (RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
4681 install_element (RMAP_NODE
, &set_ecommunity_soo_cmd
);
4682 install_element (RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
4683 #ifdef KEEP_OLD_VPN_COMMANDS
4684 install_element (RMAP_NODE
, &set_vpn_nexthop_cmd
);
4685 install_element (RMAP_NODE
, &no_set_vpn_nexthop_cmd
);
4686 #endif /* KEEP_OLD_VPN_COMMANDS */
4687 install_element (RMAP_NODE
, &set_ipx_vpn_nexthop_cmd
);
4688 install_element (RMAP_NODE
, &no_set_ipx_vpn_nexthop_cmd
);
4689 install_element (RMAP_NODE
, &set_originator_id_cmd
);
4690 install_element (RMAP_NODE
, &no_set_originator_id_cmd
);
4692 route_map_install_match (&route_match_ipv6_address_cmd
);
4693 route_map_install_match (&route_match_ipv6_next_hop_cmd
);
4694 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd
);
4695 route_map_install_set (&route_set_ipv6_nexthop_global_cmd
);
4696 route_map_install_set (&route_set_ipv6_nexthop_prefer_global_cmd
);
4697 route_map_install_set (&route_set_ipv6_nexthop_local_cmd
);
4698 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd
);
4700 install_element (RMAP_NODE
, &match_ipv6_next_hop_cmd
);
4701 install_element (RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
4702 install_element (RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
4703 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
4704 install_element (RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
4705 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
4706 install_element (RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
4707 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
4711 bgp_route_map_terminate (void)
4713 /* ToDo: Cleanup all the used memory */
4715 route_map_add_hook (NULL
);
4716 route_map_delete_hook (NULL
);
4717 route_map_event_hook (NULL
);