1 /* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32 #ifdef HAVE_LIBPCREPOSIX
33 # include <pcreposix.h>
36 #endif /* HAVE_LIBPCREPOSIX */
38 #include "sockunion.h"
42 #include "bgpd/bgpd.h"
43 #include "bgpd/bgp_table.h"
44 #include "bgpd/bgp_attr.h"
45 #include "bgpd/bgp_aspath.h"
46 #include "bgpd/bgp_packet.h"
47 #include "bgpd/bgp_route.h"
48 #include "bgpd/bgp_zebra.h"
49 #include "bgpd/bgp_regex.h"
50 #include "bgpd/bgp_community.h"
51 #include "bgpd/bgp_clist.h"
52 #include "bgpd/bgp_filter.h"
53 #include "bgpd/bgp_mplsvpn.h"
54 #include "bgpd/bgp_ecommunity.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)
89 default : (This will not be implemented by bgpd)
90 interface : (This will not be implemented by bgpd)
91 ip default : (This will not be implemented by bgpd)
93 ip precedence : (This will not be implemented by bgpd)
94 ip tos : (This will not be implemented by bgpd)
95 level : (This will not be implemented by bgpd)
96 local-preference : Done
105 set ipv6 next-hop global: Done
106 set ipv6 next-hop prefer-global: Done
107 set ipv6 next-hop local : Done
108 set as-path exclude : Done
112 /* generic value manipulation to be shared in multiple rules */
114 #define RMAP_VALUE_SET 0
115 #define RMAP_VALUE_ADD 1
116 #define RMAP_VALUE_SUB 2
126 route_value_match (struct rmap_value
*rv
, u_int32_t value
)
128 if (rv
->variable
== 0 && value
== rv
->value
)
135 route_value_adjust (struct rmap_value
*rv
, u_int32_t current
, struct peer
*peer
)
139 switch (rv
->variable
)
152 if (current
> UINT32_MAX
-value
)
154 return current
+ value
;
156 if (current
<= value
)
158 return current
- value
;
165 route_value_compile (const char *arg
)
167 u_int8_t action
= RMAP_VALUE_SET
, var
= 0;
168 unsigned long larg
= 0;
170 struct rmap_value
*rv
;
174 action
= RMAP_VALUE_ADD
;
177 else if (arg
[0] == '-')
179 action
= RMAP_VALUE_SUB
;
186 larg
= strtoul (arg
, &endptr
, 10);
187 if (*arg
== 0 || *endptr
!= 0 || errno
|| larg
> UINT32_MAX
)
192 if (strcmp(arg
, "rtt") == 0)
198 rv
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_value
));
209 route_value_free (void *rule
)
211 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
214 /* generic as path object to be shared in multiple rules */
217 route_aspath_compile (const char *arg
)
219 struct aspath
*aspath
;
221 aspath
= aspath_str2aspath (arg
);
228 route_aspath_free (void *rule
)
230 struct aspath
*aspath
= rule
;
231 aspath_free (aspath
);
234 /* 'match peer (A.B.C.D|X:X::X:X)' */
236 /* Compares the peer specified in the 'match peer' clause with the peer
237 received in bgp_info->peer. If it is the same, or if the peer structure
238 received is a peer_group containing it, returns RMAP_MATCH. */
239 static route_map_result_t
240 route_match_peer (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
244 union sockunion su_def
= { .sin
= { .sin_family
= AF_INET
,
245 .sin_addr
.s_addr
= INADDR_ANY
} };
246 struct peer_group
*group
;
248 struct listnode
*node
, *nnode
;
250 if (type
== RMAP_BGP
)
253 peer
= ((struct bgp_info
*) object
)->peer
;
255 if ( ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
) &&
256 ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_EXPORT
) )
259 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
260 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
261 if (sockunion_same (su
, &su_def
))
264 if ( CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_NETWORK
) ||
265 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
) ||
266 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_DEFAULT
))
273 if (! CHECK_FLAG (peer
->sflags
, PEER_STATUS_GROUP
))
275 if (sockunion_same (su
, &peer
->su
))
283 for (ALL_LIST_ELEMENTS (group
->peer
, node
, nnode
, peer
))
285 if (sockunion_same (su
, &peer
->su
))
295 route_match_peer_compile (const char *arg
)
300 su
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union sockunion
));
302 ret
= str2sockunion (strcmp(arg
, "local") ? arg
: "0.0.0.0", su
);
304 XFREE (MTYPE_ROUTE_MAP_COMPILED
, su
);
311 /* Free route map's compiled `ip address' value. */
313 route_match_peer_free (void *rule
)
315 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
318 /* Route map commands for ip address matching. */
319 struct route_map_rule_cmd route_match_peer_cmd
=
323 route_match_peer_compile
,
324 route_match_peer_free
327 /* `match ip address IP_ACCESS_LIST' */
329 /* Match function should return 1 if match is success else return
331 static route_map_result_t
332 route_match_ip_address (void *rule
, struct prefix
*prefix
,
333 route_map_object_t type
, void *object
)
335 struct access_list
*alist
;
336 /* struct prefix_ipv4 match; */
338 if (type
== RMAP_BGP
)
340 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
344 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
345 RMAP_NOMATCH
: RMAP_MATCH
);
350 /* Route map `ip address' match statement. `arg' should be
353 route_match_ip_address_compile (const char *arg
)
355 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
358 /* Free route map's compiled `ip address' value. */
360 route_match_ip_address_free (void *rule
)
362 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
365 /* Route map commands for ip address matching. */
366 struct route_map_rule_cmd route_match_ip_address_cmd
=
369 route_match_ip_address
,
370 route_match_ip_address_compile
,
371 route_match_ip_address_free
374 /* `match ip next-hop IP_ADDRESS' */
376 /* Match function return 1 if match is success else return zero. */
377 static route_map_result_t
378 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
379 route_map_object_t type
, void *object
)
381 struct access_list
*alist
;
382 struct bgp_info
*bgp_info
;
383 struct prefix_ipv4 p
;
385 if (type
== RMAP_BGP
)
389 p
.prefix
= bgp_info
->attr
->nexthop
;
390 p
.prefixlen
= IPV4_MAX_BITLEN
;
392 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
396 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
397 RMAP_NOMATCH
: RMAP_MATCH
);
402 /* Route map `ip next-hop' match statement. `arg' is
405 route_match_ip_next_hop_compile (const char *arg
)
407 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
410 /* Free route map's compiled `ip address' value. */
412 route_match_ip_next_hop_free (void *rule
)
414 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
417 /* Route map commands for ip next-hop matching. */
418 struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
421 route_match_ip_next_hop
,
422 route_match_ip_next_hop_compile
,
423 route_match_ip_next_hop_free
426 /* `match ip route-source ACCESS-LIST' */
428 /* Match function return 1 if match is success else return zero. */
429 static route_map_result_t
430 route_match_ip_route_source (void *rule
, struct prefix
*prefix
,
431 route_map_object_t type
, void *object
)
433 struct access_list
*alist
;
434 struct bgp_info
*bgp_info
;
436 struct prefix_ipv4 p
;
438 if (type
== RMAP_BGP
)
441 peer
= bgp_info
->peer
;
443 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
447 p
.prefix
= peer
->su
.sin
.sin_addr
;
448 p
.prefixlen
= IPV4_MAX_BITLEN
;
450 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
454 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
455 RMAP_NOMATCH
: RMAP_MATCH
);
460 /* Route map `ip route-source' match statement. `arg' is
463 route_match_ip_route_source_compile (const char *arg
)
465 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
468 /* Free route map's compiled `ip address' value. */
470 route_match_ip_route_source_free (void *rule
)
472 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
475 /* Route map commands for ip route-source matching. */
476 struct route_map_rule_cmd route_match_ip_route_source_cmd
=
479 route_match_ip_route_source
,
480 route_match_ip_route_source_compile
,
481 route_match_ip_route_source_free
484 /* `match ip address prefix-list PREFIX_LIST' */
486 static route_map_result_t
487 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
488 route_map_object_t type
, void *object
)
490 struct prefix_list
*plist
;
492 if (type
== RMAP_BGP
)
494 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
498 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
499 RMAP_NOMATCH
: RMAP_MATCH
);
505 route_match_ip_address_prefix_list_compile (const char *arg
)
507 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
511 route_match_ip_address_prefix_list_free (void *rule
)
513 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
516 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
518 "ip address prefix-list",
519 route_match_ip_address_prefix_list
,
520 route_match_ip_address_prefix_list_compile
,
521 route_match_ip_address_prefix_list_free
524 /* `match ip next-hop prefix-list PREFIX_LIST' */
526 static route_map_result_t
527 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
528 route_map_object_t type
, void *object
)
530 struct prefix_list
*plist
;
531 struct bgp_info
*bgp_info
;
532 struct prefix_ipv4 p
;
534 if (type
== RMAP_BGP
)
538 p
.prefix
= bgp_info
->attr
->nexthop
;
539 p
.prefixlen
= IPV4_MAX_BITLEN
;
541 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
545 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
546 RMAP_NOMATCH
: RMAP_MATCH
);
552 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
554 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
558 route_match_ip_next_hop_prefix_list_free (void *rule
)
560 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
563 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
565 "ip next-hop prefix-list",
566 route_match_ip_next_hop_prefix_list
,
567 route_match_ip_next_hop_prefix_list_compile
,
568 route_match_ip_next_hop_prefix_list_free
571 /* `match ip route-source prefix-list PREFIX_LIST' */
573 static route_map_result_t
574 route_match_ip_route_source_prefix_list (void *rule
, struct prefix
*prefix
,
575 route_map_object_t type
, void *object
)
577 struct prefix_list
*plist
;
578 struct bgp_info
*bgp_info
;
580 struct prefix_ipv4 p
;
582 if (type
== RMAP_BGP
)
585 peer
= bgp_info
->peer
;
587 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
591 p
.prefix
= peer
->su
.sin
.sin_addr
;
592 p
.prefixlen
= IPV4_MAX_BITLEN
;
594 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
598 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
599 RMAP_NOMATCH
: RMAP_MATCH
);
605 route_match_ip_route_source_prefix_list_compile (const char *arg
)
607 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
611 route_match_ip_route_source_prefix_list_free (void *rule
)
613 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
616 struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd
=
618 "ip route-source prefix-list",
619 route_match_ip_route_source_prefix_list
,
620 route_match_ip_route_source_prefix_list_compile
,
621 route_match_ip_route_source_prefix_list_free
624 /* `match local-preference LOCAL-PREF' */
626 /* Match function return 1 if match is success else return zero. */
627 static route_map_result_t
628 route_match_local_pref (void *rule
, struct prefix
*prefix
,
629 route_map_object_t type
, void *object
)
631 u_int32_t
*local_pref
;
632 struct bgp_info
*bgp_info
;
634 if (type
== RMAP_BGP
)
639 if (bgp_info
->attr
->local_pref
== *local_pref
)
647 /* Route map `match local-preference' match statement.
648 `arg' is local-pref value */
650 route_match_local_pref_compile (const char *arg
)
652 u_int32_t
*local_pref
;
654 unsigned long tmpval
;
656 /* Locpref value shoud be integer. */
657 if (! all_digit (arg
))
661 tmpval
= strtoul (arg
, &endptr
, 10);
662 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
665 local_pref
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
670 *local_pref
= tmpval
;
674 /* Free route map's compiled `match local-preference' value. */
676 route_match_local_pref_free (void *rule
)
678 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
681 /* Route map commands for metric matching. */
682 struct route_map_rule_cmd route_match_local_pref_cmd
=
685 route_match_local_pref
,
686 route_match_local_pref_compile
,
687 route_match_local_pref_free
690 /* `match metric METRIC' */
692 /* Match function return 1 if match is success else return zero. */
693 static route_map_result_t
694 route_match_metric (void *rule
, struct prefix
*prefix
,
695 route_map_object_t type
, void *object
)
697 struct rmap_value
*rv
;
698 struct bgp_info
*bgp_info
;
700 if (type
== RMAP_BGP
)
704 return route_value_match(rv
, bgp_info
->attr
->med
);
709 /* Route map commands for metric matching. */
710 struct route_map_rule_cmd route_match_metric_cmd
=
718 /* `match as-path ASPATH' */
720 /* Match function for as-path match. I assume given object is */
721 static route_map_result_t
722 route_match_aspath (void *rule
, struct prefix
*prefix
,
723 route_map_object_t type
, void *object
)
726 struct as_list
*as_list
;
727 struct bgp_info
*bgp_info
;
729 if (type
== RMAP_BGP
)
731 as_list
= as_list_lookup ((char *) rule
);
738 return ((as_list_apply (as_list
, bgp_info
->attr
->aspath
) == AS_FILTER_DENY
) ? RMAP_NOMATCH
: RMAP_MATCH
);
743 /* Compile function for as-path match. */
745 route_match_aspath_compile (const char *arg
)
747 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
750 /* Compile function for as-path match. */
752 route_match_aspath_free (void *rule
)
754 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
757 /* Route map commands for aspath matching. */
758 struct route_map_rule_cmd route_match_aspath_cmd
=
762 route_match_aspath_compile
,
763 route_match_aspath_free
766 /* `match community COMMUNIY' */
767 struct rmap_community
773 /* Match function for community match. */
774 static route_map_result_t
775 route_match_community (void *rule
, struct prefix
*prefix
,
776 route_map_object_t type
, void *object
)
778 struct community_list
*list
;
779 struct bgp_info
*bgp_info
;
780 struct rmap_community
*rcom
;
782 if (type
== RMAP_BGP
)
787 list
= community_list_lookup (bgp_clist
, rcom
->name
, COMMUNITY_LIST_MASTER
);
793 if (community_list_exact_match (bgp_info
->attr
->community
, list
))
798 if (community_list_match (bgp_info
->attr
->community
, list
))
805 /* Compile function for community match. */
807 route_match_community_compile (const char *arg
)
809 struct rmap_community
*rcom
;
813 rcom
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_community
));
815 p
= strchr (arg
, ' ');
819 rcom
->name
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
820 memcpy (rcom
->name
, arg
, len
);
825 rcom
->name
= XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
831 /* Compile function for community match. */
833 route_match_community_free (void *rule
)
835 struct rmap_community
*rcom
= rule
;
837 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
838 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
);
841 /* Route map commands for community matching. */
842 struct route_map_rule_cmd route_match_community_cmd
=
845 route_match_community
,
846 route_match_community_compile
,
847 route_match_community_free
850 /* Match function for extcommunity match. */
851 static route_map_result_t
852 route_match_ecommunity (void *rule
, struct prefix
*prefix
,
853 route_map_object_t type
, void *object
)
855 struct community_list
*list
;
856 struct bgp_info
*bgp_info
;
858 if (type
== RMAP_BGP
)
862 if (!bgp_info
->attr
->extra
)
865 list
= community_list_lookup (bgp_clist
, (char *) rule
,
866 EXTCOMMUNITY_LIST_MASTER
);
870 if (ecommunity_list_match (bgp_info
->attr
->extra
->ecommunity
, list
))
876 /* Compile function for extcommunity match. */
878 route_match_ecommunity_compile (const char *arg
)
880 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
883 /* Compile function for extcommunity match. */
885 route_match_ecommunity_free (void *rule
)
887 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
890 /* Route map commands for community matching. */
891 struct route_map_rule_cmd route_match_ecommunity_cmd
=
894 route_match_ecommunity
,
895 route_match_ecommunity_compile
,
896 route_match_ecommunity_free
899 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
900 and `address-family vpnv4'. */
903 static route_map_result_t
904 route_match_origin (void *rule
, struct prefix
*prefix
,
905 route_map_object_t type
, void *object
)
908 struct bgp_info
*bgp_info
;
910 if (type
== RMAP_BGP
)
915 if (bgp_info
->attr
->origin
== *origin
)
923 route_match_origin_compile (const char *arg
)
927 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
929 if (strcmp (arg
, "igp") == 0)
931 else if (strcmp (arg
, "egp") == 0)
939 /* Free route map's compiled `ip address' value. */
941 route_match_origin_free (void *rule
)
943 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
946 /* Route map commands for origin matching. */
947 struct route_map_rule_cmd route_match_origin_cmd
=
951 route_match_origin_compile
,
952 route_match_origin_free
955 /* match probability { */
957 static route_map_result_t
958 route_match_probability (void *rule
, struct prefix
*prefix
,
959 route_map_object_t type
, void *object
)
963 switch (*(long *) rule
)
966 case RAND_MAX
: return RMAP_MATCH
;
968 if (r
< *(long *) rule
)
978 route_match_probability_compile (const char *arg
)
984 lobule
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (long));
988 case 0: *lobule
= 0; break;
989 case 100: *lobule
= RAND_MAX
; break;
990 default: *lobule
= RAND_MAX
/ 100 * perc
;
997 route_match_probability_free (void *rule
)
999 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1002 struct route_map_rule_cmd route_match_probability_cmd
=
1005 route_match_probability
,
1006 route_match_probability_compile
,
1007 route_match_probability_free
1010 /* `match interface IFNAME' */
1011 /* Match function should return 1 if match is success else return
1013 static route_map_result_t
1014 route_match_interface (void *rule
, struct prefix
*prefix
,
1015 route_map_object_t type
, void *object
)
1017 struct interface
*ifp
;
1018 struct bgp_info
*info
;
1020 if (type
== RMAP_BGP
)
1024 if (!info
|| !info
->attr
)
1025 return RMAP_NOMATCH
;
1027 ifp
= if_lookup_by_name_all_vrf ((char *)rule
);
1029 if (ifp
== NULL
|| ifp
->ifindex
!= info
->attr
->nh_ifindex
)
1030 return RMAP_NOMATCH
;
1034 return RMAP_NOMATCH
;
1037 /* Route map `interface' match statement. `arg' should be
1040 route_match_interface_compile (const char *arg
)
1042 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1045 /* Free route map's compiled `interface' value. */
1047 route_match_interface_free (void *rule
)
1049 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1052 /* Route map commands for ip address matching. */
1053 struct route_map_rule_cmd route_match_interface_cmd
=
1056 route_match_interface
,
1057 route_match_interface_compile
,
1058 route_match_interface_free
1063 /* `set ip next-hop IP_ADDRESS' */
1065 /* Match function return 1 if match is success else return zero. */
1066 static route_map_result_t
1067 route_match_tag (void *rule
, struct prefix
*prefix
,
1068 route_map_object_t type
, void *object
)
1071 struct bgp_info
*bgp_info
;
1073 if (type
== RMAP_BGP
)
1078 if (!bgp_info
->attr
->extra
)
1079 return RMAP_NOMATCH
;
1081 return ((bgp_info
->attr
->extra
->tag
== *tag
)? RMAP_MATCH
: RMAP_NOMATCH
);
1084 return RMAP_NOMATCH
;
1088 /* Route map commands for tag matching. */
1089 static struct route_map_rule_cmd route_match_tag_cmd
=
1093 route_map_rule_tag_compile
,
1094 route_map_rule_tag_free
,
1098 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1099 struct rmap_ip_nexthop_set
1101 struct in_addr
*address
;
1106 static route_map_result_t
1107 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
1108 route_map_object_t type
, void *object
)
1110 struct rmap_ip_nexthop_set
*rins
= rule
;
1111 struct bgp_info
*bgp_info
;
1114 if (type
== RMAP_BGP
)
1117 peer
= bgp_info
->peer
;
1119 if (rins
->unchanged
)
1121 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1122 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1124 else if (rins
->peer_address
)
1126 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
1127 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1129 && sockunion_family (peer
->su_remote
) == AF_INET
)
1131 bgp_info
->attr
->nexthop
.s_addr
= sockunion2ip (peer
->su_remote
);
1132 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1134 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
1136 /* The next hop value will be set as part of packet rewrite.
1137 * Set the flags here to indicate that rewrite needs to be done.
1138 * Also, clear the value.
1140 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1141 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1142 bgp_info
->attr
->nexthop
.s_addr
= 0;
1147 /* Set next hop value. */
1148 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1149 bgp_info
->attr
->nexthop
= *rins
->address
;
1150 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1151 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1158 /* Route map `ip nexthop' compile function. Given string is converted
1159 to struct in_addr structure. */
1161 route_set_ip_nexthop_compile (const char *arg
)
1163 struct rmap_ip_nexthop_set
*rins
;
1164 struct in_addr
*address
= NULL
;
1165 int peer_address
= 0;
1169 if (strcmp (arg
, "peer-address") == 0)
1171 else if (strcmp (arg
, "unchanged") == 0)
1175 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
1176 ret
= inet_aton (arg
, address
);
1180 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
1185 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_ip_nexthop_set
));
1187 rins
->address
= address
;
1188 rins
->peer_address
= peer_address
;
1189 rins
->unchanged
= unchanged
;
1194 /* Free route map's compiled `ip nexthop' value. */
1196 route_set_ip_nexthop_free (void *rule
)
1198 struct rmap_ip_nexthop_set
*rins
= rule
;
1201 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1203 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
);
1206 /* Route map commands for ip nexthop set. */
1207 struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
1210 route_set_ip_nexthop
,
1211 route_set_ip_nexthop_compile
,
1212 route_set_ip_nexthop_free
1215 /* `set local-preference LOCAL_PREF' */
1217 /* Set local preference. */
1218 static route_map_result_t
1219 route_set_local_pref (void *rule
, struct prefix
*prefix
,
1220 route_map_object_t type
, void *object
)
1222 struct rmap_value
*rv
;
1223 struct bgp_info
*bgp_info
;
1224 u_int32_t locpref
= 0;
1226 if (type
== RMAP_BGP
)
1228 /* Fetch routemap's rule information. */
1232 /* Set local preference value. */
1233 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
1234 locpref
= bgp_info
->attr
->local_pref
;
1236 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1237 bgp_info
->attr
->local_pref
= route_value_adjust(rv
, locpref
, bgp_info
->peer
);
1243 /* Set local preference rule structure. */
1244 struct route_map_rule_cmd route_set_local_pref_cmd
=
1247 route_set_local_pref
,
1248 route_value_compile
,
1252 /* `set weight WEIGHT' */
1255 static route_map_result_t
1256 route_set_weight (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
1259 struct rmap_value
*rv
;
1260 struct bgp_info
*bgp_info
;
1263 if (type
== RMAP_BGP
)
1265 /* Fetch routemap's rule information. */
1269 /* Set weight value. */
1270 weight
= route_value_adjust(rv
, 0, bgp_info
->peer
);
1272 (bgp_attr_extra_get (bgp_info
->attr
))->weight
= weight
;
1273 else if (bgp_info
->attr
->extra
)
1274 bgp_info
->attr
->extra
->weight
= 0;
1280 /* Set local preference rule structure. */
1281 struct route_map_rule_cmd route_set_weight_cmd
=
1285 route_value_compile
,
1289 /* `set metric METRIC' */
1291 /* Set metric to attribute. */
1292 static route_map_result_t
1293 route_set_metric (void *rule
, struct prefix
*prefix
,
1294 route_map_object_t type
, void *object
)
1296 struct rmap_value
*rv
;
1297 struct bgp_info
*bgp_info
;
1300 if (type
== RMAP_BGP
)
1302 /* Fetch routemap's rule information. */
1306 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1307 med
= bgp_info
->attr
->med
;
1309 bgp_info
->attr
->med
= route_value_adjust(rv
, med
, bgp_info
->peer
);
1310 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
1315 /* Set metric rule structure. */
1316 struct route_map_rule_cmd route_set_metric_cmd
=
1320 route_value_compile
,
1324 /* `set as-path prepend ASPATH' */
1326 /* For AS path prepend mechanism. */
1327 static route_map_result_t
1328 route_set_aspath_prepend (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1330 struct aspath
*aspath
;
1332 struct bgp_info
*binfo
;
1334 if (type
== RMAP_BGP
)
1338 if (binfo
->attr
->aspath
->refcnt
)
1339 new = aspath_dup (binfo
->attr
->aspath
);
1341 new = binfo
->attr
->aspath
;
1343 if ((uintptr_t)rule
> 10)
1346 aspath_prepend (aspath
, new);
1350 as_t as
= aspath_leftmost(new);
1351 if (!as
) as
= binfo
->peer
->as
;
1352 new = aspath_add_seq_n (new, as
, (uintptr_t) rule
);
1355 binfo
->attr
->aspath
= new;
1362 route_set_aspath_prepend_compile (const char *arg
)
1366 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
< 10)
1367 return (void*)(uintptr_t)num
;
1369 return route_aspath_compile(arg
);
1373 route_set_aspath_prepend_free (void *rule
)
1375 if ((uintptr_t)rule
> 10)
1376 route_aspath_free(rule
);
1380 /* Set as-path prepend rule structure. */
1381 struct route_map_rule_cmd route_set_aspath_prepend_cmd
=
1384 route_set_aspath_prepend
,
1385 route_set_aspath_prepend_compile
,
1386 route_set_aspath_prepend_free
,
1389 /* `set as-path exclude ASn' */
1391 /* For ASN exclude mechanism.
1392 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1393 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1395 static route_map_result_t
1396 route_set_aspath_exclude (void *rule
, struct prefix
*dummy
, route_map_object_t type
, void *object
)
1398 struct aspath
* new_path
, * exclude_path
;
1399 struct bgp_info
*binfo
;
1401 if (type
== RMAP_BGP
)
1403 exclude_path
= rule
;
1405 if (binfo
->attr
->aspath
->refcnt
)
1406 new_path
= aspath_dup (binfo
->attr
->aspath
);
1408 new_path
= binfo
->attr
->aspath
;
1409 binfo
->attr
->aspath
= aspath_filter_exclude (new_path
, exclude_path
);
1414 /* Set ASn exlude rule structure. */
1415 struct route_map_rule_cmd route_set_aspath_exclude_cmd
=
1418 route_set_aspath_exclude
,
1419 route_aspath_compile
,
1423 /* `set community COMMUNITY' */
1426 struct community
*com
;
1431 /* For community set mechanism. */
1432 static route_map_result_t
1433 route_set_community (void *rule
, struct prefix
*prefix
,
1434 route_map_object_t type
, void *object
)
1436 struct rmap_com_set
*rcs
;
1437 struct bgp_info
*binfo
;
1439 struct community
*new = NULL
;
1440 struct community
*old
;
1441 struct community
*merge
;
1443 if (type
== RMAP_BGP
)
1448 old
= attr
->community
;
1453 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
));
1454 attr
->community
= NULL
;
1455 /* See the longer comment down below. */
1456 if (old
&& old
->refcnt
== 0)
1457 community_free(old
);
1461 /* "additive" case. */
1462 if (rcs
->additive
&& old
)
1464 merge
= community_merge (community_dup (old
), rcs
->com
);
1466 /* HACK: if the old community is not intern'd,
1467 * we should free it here, or all reference to it may be lost.
1468 * Really need to cleanup attribute caching sometime.
1470 if (old
->refcnt
== 0)
1471 community_free (old
);
1472 new = community_uniq_sort (merge
);
1473 community_free (merge
);
1476 new = community_dup (rcs
->com
);
1478 /* will be interned by caller if required */
1479 attr
->community
= new;
1481 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1487 /* Compile function for set community. */
1489 route_set_community_compile (const char *arg
)
1491 struct rmap_com_set
*rcs
;
1492 struct community
*com
= NULL
;
1497 if (strcmp (arg
, "none") == 0)
1501 sp
= strstr (arg
, "additive");
1505 /* "additive" keyworkd is included. */
1510 com
= community_str2com (arg
);
1519 rcs
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_com_set
));
1521 rcs
->additive
= additive
;
1527 /* Free function for set community. */
1529 route_set_community_free (void *rule
)
1531 struct rmap_com_set
*rcs
= rule
;
1534 community_free (rcs
->com
);
1535 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1538 /* Set community rule structure. */
1539 struct route_map_rule_cmd route_set_community_cmd
=
1542 route_set_community
,
1543 route_set_community_compile
,
1544 route_set_community_free
,
1547 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
1549 /* For community set mechanism. */
1550 static route_map_result_t
1551 route_set_community_delete (void *rule
, struct prefix
*prefix
,
1552 route_map_object_t type
, void *object
)
1554 struct community_list
*list
;
1555 struct community
*merge
;
1556 struct community
*new;
1557 struct community
*old
;
1558 struct bgp_info
*binfo
;
1560 if (type
== RMAP_BGP
)
1566 list
= community_list_lookup (bgp_clist
, rule
, COMMUNITY_LIST_MASTER
);
1567 old
= binfo
->attr
->community
;
1571 merge
= community_list_match_delete (community_dup (old
), list
);
1572 new = community_uniq_sort (merge
);
1573 community_free (merge
);
1575 /* HACK: if the old community is not intern'd,
1576 * we should free it here, or all reference to it may be lost.
1577 * Really need to cleanup attribute caching sometime.
1579 if (old
->refcnt
== 0)
1580 community_free (old
);
1584 binfo
->attr
->community
= NULL
;
1585 binfo
->attr
->flag
&= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1586 community_free (new);
1590 binfo
->attr
->community
= new;
1591 binfo
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1599 /* Compile function for set community. */
1601 route_set_community_delete_compile (const char *arg
)
1607 p
= strchr (arg
, ' ');
1611 str
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1612 memcpy (str
, arg
, len
);
1620 /* Free function for set community. */
1622 route_set_community_delete_free (void *rule
)
1624 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1627 /* Set community rule structure. */
1628 struct route_map_rule_cmd route_set_community_delete_cmd
=
1631 route_set_community_delete
,
1632 route_set_community_delete_compile
,
1633 route_set_community_delete_free
,
1636 /* `set extcommunity rt COMMUNITY' */
1638 /* For community set mechanism. Used by _rt and _soo. */
1639 static route_map_result_t
1640 route_set_ecommunity (void *rule
, struct prefix
*prefix
,
1641 route_map_object_t type
, void *object
)
1643 struct ecommunity
*ecom
;
1644 struct ecommunity
*new_ecom
;
1645 struct ecommunity
*old_ecom
;
1646 struct bgp_info
*bgp_info
;
1648 if (type
== RMAP_BGP
)
1656 /* We assume additive for Extended Community. */
1657 old_ecom
= (bgp_attr_extra_get (bgp_info
->attr
))->ecommunity
;
1661 new_ecom
= ecommunity_merge (ecommunity_dup (old_ecom
), ecom
);
1663 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1664 * ->refcnt = 0 => set by a previous route-map statement */
1665 if (!old_ecom
->refcnt
)
1666 ecommunity_free (&old_ecom
);
1669 new_ecom
= ecommunity_dup (ecom
);
1671 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1672 bgp_info
->attr
->extra
->ecommunity
= new_ecom
;
1674 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
);
1679 /* Compile function for set community. */
1681 route_set_ecommunity_rt_compile (const char *arg
)
1683 struct ecommunity
*ecom
;
1685 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
1688 return ecommunity_intern (ecom
);
1691 /* Free function for set community. Used by _rt and _soo */
1693 route_set_ecommunity_free (void *rule
)
1695 struct ecommunity
*ecom
= rule
;
1696 ecommunity_unintern (&ecom
);
1699 /* Set community rule structure. */
1700 struct route_map_rule_cmd route_set_ecommunity_rt_cmd
=
1703 route_set_ecommunity
,
1704 route_set_ecommunity_rt_compile
,
1705 route_set_ecommunity_free
,
1708 /* `set extcommunity soo COMMUNITY' */
1710 /* Compile function for set community. */
1712 route_set_ecommunity_soo_compile (const char *arg
)
1714 struct ecommunity
*ecom
;
1716 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
1720 return ecommunity_intern (ecom
);
1723 /* Set community rule structure. */
1724 struct route_map_rule_cmd route_set_ecommunity_soo_cmd
=
1727 route_set_ecommunity
,
1728 route_set_ecommunity_soo_compile
,
1729 route_set_ecommunity_free
,
1732 /* `set origin ORIGIN' */
1734 /* For origin set. */
1735 static route_map_result_t
1736 route_set_origin (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1739 struct bgp_info
*bgp_info
;
1741 if (type
== RMAP_BGP
)
1746 bgp_info
->attr
->origin
= *origin
;
1752 /* Compile function for origin set. */
1754 route_set_origin_compile (const char *arg
)
1758 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
1760 if (strcmp (arg
, "igp") == 0)
1762 else if (strcmp (arg
, "egp") == 0)
1770 /* Compile function for origin set. */
1772 route_set_origin_free (void *rule
)
1774 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1777 /* Set origin rule structure. */
1778 struct route_map_rule_cmd route_set_origin_cmd
=
1782 route_set_origin_compile
,
1783 route_set_origin_free
,
1786 /* `set atomic-aggregate' */
1788 /* For atomic aggregate set. */
1789 static route_map_result_t
1790 route_set_atomic_aggregate (void *rule
, struct prefix
*prefix
,
1791 route_map_object_t type
, void *object
)
1793 struct bgp_info
*bgp_info
;
1795 if (type
== RMAP_BGP
)
1798 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
1804 /* Compile function for atomic aggregate. */
1806 route_set_atomic_aggregate_compile (const char *arg
)
1811 /* Compile function for atomic aggregate. */
1813 route_set_atomic_aggregate_free (void *rule
)
1818 /* Set atomic aggregate rule structure. */
1819 struct route_map_rule_cmd route_set_atomic_aggregate_cmd
=
1822 route_set_atomic_aggregate
,
1823 route_set_atomic_aggregate_compile
,
1824 route_set_atomic_aggregate_free
,
1827 /* `set aggregator as AS A.B.C.D' */
1831 struct in_addr address
;
1834 static route_map_result_t
1835 route_set_aggregator_as (void *rule
, struct prefix
*prefix
,
1836 route_map_object_t type
, void *object
)
1838 struct bgp_info
*bgp_info
;
1839 struct aggregator
*aggregator
;
1840 struct attr_extra
*ae
;
1842 if (type
== RMAP_BGP
)
1846 ae
= bgp_attr_extra_get (bgp_info
->attr
);
1848 ae
->aggregator_as
= aggregator
->as
;
1849 ae
->aggregator_addr
= aggregator
->address
;
1850 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
);
1857 route_set_aggregator_as_compile (const char *arg
)
1859 struct aggregator
*aggregator
;
1863 aggregator
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct aggregator
));
1864 sscanf (arg
, "%s %s", as
, address
);
1866 aggregator
->as
= strtoul (as
, NULL
, 10);
1867 inet_aton (address
, &aggregator
->address
);
1873 route_set_aggregator_as_free (void *rule
)
1875 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1878 struct route_map_rule_cmd route_set_aggregator_as_cmd
=
1881 route_set_aggregator_as
,
1882 route_set_aggregator_as_compile
,
1883 route_set_aggregator_as_free
,
1886 /* Set tag to object. object must be pointer to struct bgp_info */
1887 static route_map_result_t
1888 route_set_tag (void *rule
, struct prefix
*prefix
,
1889 route_map_object_t type
, void *object
)
1892 struct bgp_info
*bgp_info
;
1893 struct attr_extra
*ae
;
1895 if (type
== RMAP_BGP
)
1899 ae
= bgp_attr_extra_get (bgp_info
->attr
);
1909 /* Route map commands for tag set. */
1910 static struct route_map_rule_cmd route_set_tag_cmd
=
1914 route_map_rule_tag_compile
,
1915 route_map_rule_tag_free
,
1919 /* `match ipv6 address IP_ACCESS_LIST' */
1921 static route_map_result_t
1922 route_match_ipv6_address (void *rule
, struct prefix
*prefix
,
1923 route_map_object_t type
, void *object
)
1925 struct access_list
*alist
;
1927 if (type
== RMAP_BGP
)
1929 alist
= access_list_lookup (AFI_IP6
, (char *) rule
);
1931 return RMAP_NOMATCH
;
1933 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
1934 RMAP_NOMATCH
: RMAP_MATCH
);
1936 return RMAP_NOMATCH
;
1940 route_match_ipv6_address_compile (const char *arg
)
1942 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1946 route_match_ipv6_address_free (void *rule
)
1948 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1951 /* Route map commands for ip address matching. */
1952 struct route_map_rule_cmd route_match_ipv6_address_cmd
=
1955 route_match_ipv6_address
,
1956 route_match_ipv6_address_compile
,
1957 route_match_ipv6_address_free
1960 /* `match ipv6 next-hop IP_ADDRESS' */
1962 static route_map_result_t
1963 route_match_ipv6_next_hop (void *rule
, struct prefix
*prefix
,
1964 route_map_object_t type
, void *object
)
1966 struct in6_addr
*addr
= rule
;
1967 struct bgp_info
*bgp_info
;
1969 if (type
== RMAP_BGP
)
1973 if (!bgp_info
->attr
->extra
)
1974 return RMAP_NOMATCH
;
1976 if (IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_global
, addr
))
1979 if (bgp_info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
&&
1980 IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_local
, rule
))
1983 return RMAP_NOMATCH
;
1986 return RMAP_NOMATCH
;
1990 route_match_ipv6_next_hop_compile (const char *arg
)
1992 struct in6_addr
*address
;
1995 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
1997 ret
= inet_pton (AF_INET6
, arg
, address
);
2000 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2008 route_match_ipv6_next_hop_free (void *rule
)
2010 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2013 struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
=
2016 route_match_ipv6_next_hop
,
2017 route_match_ipv6_next_hop_compile
,
2018 route_match_ipv6_next_hop_free
2021 /* `match ipv6 address prefix-list PREFIX_LIST' */
2023 static route_map_result_t
2024 route_match_ipv6_address_prefix_list (void *rule
, struct prefix
*prefix
,
2025 route_map_object_t type
, void *object
)
2027 struct prefix_list
*plist
;
2029 if (type
== RMAP_BGP
)
2031 plist
= prefix_list_lookup (AFI_IP6
, (char *) rule
);
2033 return RMAP_NOMATCH
;
2035 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
2036 RMAP_NOMATCH
: RMAP_MATCH
);
2038 return RMAP_NOMATCH
;
2042 route_match_ipv6_address_prefix_list_compile (const char *arg
)
2044 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2048 route_match_ipv6_address_prefix_list_free (void *rule
)
2050 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2053 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
=
2055 "ipv6 address prefix-list",
2056 route_match_ipv6_address_prefix_list
,
2057 route_match_ipv6_address_prefix_list_compile
,
2058 route_match_ipv6_address_prefix_list_free
2061 /* `set ipv6 nexthop global IP_ADDRESS' */
2063 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2064 static route_map_result_t
2065 route_set_ipv6_nexthop_global (void *rule
, struct prefix
*prefix
,
2066 route_map_object_t type
, void *object
)
2068 struct in6_addr
*address
;
2069 struct bgp_info
*bgp_info
;
2071 if (type
== RMAP_BGP
)
2073 /* Fetch routemap's rule information. */
2077 /* Set next hop value. */
2078 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= *address
;
2080 /* Set nexthop length. */
2081 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2082 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
2084 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2085 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
2091 /* Route map `ip next-hop' compile function. Given string is converted
2092 to struct in_addr structure. */
2094 route_set_ipv6_nexthop_global_compile (const char *arg
)
2097 struct in6_addr
*address
;
2099 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2101 ret
= inet_pton (AF_INET6
, arg
, address
);
2105 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2112 /* Free route map's compiled `ip next-hop' value. */
2114 route_set_ipv6_nexthop_global_free (void *rule
)
2116 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2119 /* Route map commands for ip nexthop set. */
2120 struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd
=
2122 "ipv6 next-hop global",
2123 route_set_ipv6_nexthop_global
,
2124 route_set_ipv6_nexthop_global_compile
,
2125 route_set_ipv6_nexthop_global_free
2128 /* Set next-hop preference value. */
2129 static route_map_result_t
2130 route_set_ipv6_nexthop_prefer_global (void *rule
, struct prefix
*prefix
,
2131 route_map_object_t type
, void *object
)
2133 struct bgp_info
*bgp_info
;
2136 if (type
== RMAP_BGP
)
2138 /* Fetch routemap's rule information. */
2140 peer
= bgp_info
->peer
;
2142 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2143 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2145 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2147 /* Set next hop preference to global */
2148 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= TRUE
;
2149 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2150 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2154 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= FALSE
;
2155 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2156 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2163 route_set_ipv6_nexthop_prefer_global_compile (const char *arg
)
2167 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2173 /* Free route map's compiled `ip next-hop' value. */
2175 route_set_ipv6_nexthop_prefer_global_free (void *rule
)
2177 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2180 /* Route map commands for ip nexthop set preferred. */
2181 struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd
=
2183 "ipv6 next-hop prefer-global",
2184 route_set_ipv6_nexthop_prefer_global
,
2185 route_set_ipv6_nexthop_prefer_global_compile
,
2186 route_set_ipv6_nexthop_prefer_global_free
2189 /* `set ipv6 nexthop local IP_ADDRESS' */
2191 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2192 static route_map_result_t
2193 route_set_ipv6_nexthop_local (void *rule
, struct prefix
*prefix
,
2194 route_map_object_t type
, void *object
)
2196 struct in6_addr
*address
;
2197 struct bgp_info
*bgp_info
;
2199 if (type
== RMAP_BGP
)
2201 /* Fetch routemap's rule information. */
2205 /* Set next hop value. */
2206 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= *address
;
2208 /* Set nexthop length. */
2209 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
2210 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
2212 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2213 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
2219 /* Route map `ip nexthop' compile function. Given string is converted
2220 to struct in_addr structure. */
2222 route_set_ipv6_nexthop_local_compile (const char *arg
)
2225 struct in6_addr
*address
;
2227 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2229 ret
= inet_pton (AF_INET6
, arg
, address
);
2233 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2240 /* Free route map's compiled `ip nexthop' value. */
2242 route_set_ipv6_nexthop_local_free (void *rule
)
2244 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2247 /* Route map commands for ip nexthop set. */
2248 struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
2250 "ipv6 next-hop local",
2251 route_set_ipv6_nexthop_local
,
2252 route_set_ipv6_nexthop_local_compile
,
2253 route_set_ipv6_nexthop_local_free
2256 /* `set ipv6 nexthop peer-address' */
2258 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2259 static route_map_result_t
2260 route_set_ipv6_nexthop_peer (void *rule
, struct prefix
*prefix
,
2261 route_map_object_t type
, void *object
)
2263 struct in6_addr peer_address
;
2264 struct bgp_info
*bgp_info
;
2267 if (type
== RMAP_BGP
)
2269 /* Fetch routemap's rule information. */
2271 peer
= bgp_info
->peer
;
2273 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2274 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2276 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2278 peer_address
= peer
->su_remote
->sin6
.sin6_addr
;
2279 /* Set next hop value and length in attribute. */
2280 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
))
2282 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= peer_address
;
2283 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= 32)
2284 bgp_info
->attr
->extra
->mp_nexthop_len
= 32;
2288 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= peer_address
;
2289 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2290 bgp_info
->attr
->extra
->mp_nexthop_len
= 16;
2294 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
2296 /* The next hop value will be set as part of packet rewrite.
2297 * Set the flags here to indicate that rewrite needs to be done.
2298 * Also, clear the value - we clear both global and link-local
2299 * nexthops, whether we send one or both is determined elsewhere.
2301 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2302 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
2303 /* clear next hop value. */
2304 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
),
2305 0, sizeof (struct in6_addr
));
2306 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
),
2307 0, sizeof (struct in6_addr
));
2314 /* Route map `ip next-hop' compile function. Given string is converted
2315 to struct in_addr structure. */
2317 route_set_ipv6_nexthop_peer_compile (const char *arg
)
2321 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2327 /* Free route map's compiled `ip next-hop' value. */
2329 route_set_ipv6_nexthop_peer_free (void *rule
)
2331 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2334 /* Route map commands for ip nexthop set. */
2335 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
=
2337 "ipv6 next-hop peer-address",
2338 route_set_ipv6_nexthop_peer
,
2339 route_set_ipv6_nexthop_peer_compile
,
2340 route_set_ipv6_nexthop_peer_free
2343 /* `set vpnv4 nexthop A.B.C.D' */
2345 static route_map_result_t
2346 route_set_vpnv4_nexthop (void *rule
, struct prefix
*prefix
,
2347 route_map_object_t type
, void *object
)
2349 struct in_addr
*address
;
2350 struct bgp_info
*bgp_info
;
2352 if (type
== RMAP_BGP
)
2354 /* Fetch routemap's rule information. */
2358 /* Set next hop value. */
2359 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global_in
= *address
;
2360 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_len
= 4;
2367 route_set_vpnv4_nexthop_compile (const char *arg
)
2370 struct in_addr
*address
;
2372 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2374 ret
= inet_aton (arg
, address
);
2378 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2386 route_set_vpnv4_nexthop_free (void *rule
)
2388 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2391 /* Route map commands for ip nexthop set. */
2392 struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
=
2395 route_set_vpnv4_nexthop
,
2396 route_set_vpnv4_nexthop_compile
,
2397 route_set_vpnv4_nexthop_free
2400 /* `set originator-id' */
2402 /* For origin set. */
2403 static route_map_result_t
2404 route_set_originator_id (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
2406 struct in_addr
*address
;
2407 struct bgp_info
*bgp_info
;
2409 if (type
== RMAP_BGP
)
2414 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
);
2415 (bgp_attr_extra_get (bgp_info
->attr
))->originator_id
= *address
;
2421 /* Compile function for originator-id set. */
2423 route_set_originator_id_compile (const char *arg
)
2426 struct in_addr
*address
;
2428 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2430 ret
= inet_aton (arg
, address
);
2434 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2441 /* Compile function for originator_id set. */
2443 route_set_originator_id_free (void *rule
)
2445 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2448 /* Set originator-id rule structure. */
2449 struct route_map_rule_cmd route_set_originator_id_cmd
=
2452 route_set_originator_id
,
2453 route_set_originator_id_compile
,
2454 route_set_originator_id_free
,
2457 /* Add bgp route map rule. */
2459 bgp_route_match_add (struct vty
*vty
,
2460 const char *command
, const char *arg
,
2461 route_map_event_t type
)
2463 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
2466 ret
= route_map_add_match (index
, command
, arg
);
2471 case RMAP_RULE_MISSING
:
2472 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2474 case RMAP_COMPILE_ERROR
:
2475 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2480 if (type
!= RMAP_EVENT_MATCH_ADDED
)
2482 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
2488 /* Delete bgp route map rule. */
2490 bgp_route_match_delete (struct vty
*vty
,
2491 const char *command
, const char *arg
,
2492 route_map_event_t type
)
2494 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
2496 char *dep_name
= NULL
;
2498 char *rmap_name
= NULL
;
2500 if (type
!= RMAP_EVENT_MATCH_DELETED
)
2502 /* ignore the mundane, the types without any dependency */
2505 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
2506 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
2510 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
2512 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
2515 ret
= route_map_delete_match (index
, command
, dep_name
);
2520 case RMAP_RULE_MISSING
:
2521 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2523 case RMAP_COMPILE_ERROR
:
2524 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2528 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2530 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2534 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
2535 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
2538 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2540 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2546 * This is the workhorse routine for processing in/out routemap
2550 bgp_route_map_process_peer (const char *rmap_name
, struct route_map
*map
,
2551 struct peer
*peer
, int afi
, int safi
,
2556 struct bgp_filter
*filter
;
2558 if (!peer
|| !rmap_name
)
2561 filter
= &peer
->filter
[afi
][safi
];
2563 * in is for non-route-server clients,
2564 * out is for all peers
2566 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2568 if (filter
->map
[RMAP_IN
].name
&&
2569 (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0))
2571 filter
->map
[RMAP_IN
].map
= map
;
2573 if (route_update
&& peer
->status
== Established
)
2575 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2576 PEER_FLAG_SOFT_RECONFIG
))
2578 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2579 zlog_debug("Processing route_map %s update on "
2580 "peer %s (inbound, soft-reconfig)",
2581 rmap_name
, peer
->host
);
2583 bgp_soft_reconfig_in (peer
, afi
, safi
);
2585 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2586 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2589 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2590 zlog_debug("Processing route_map %s update on "
2591 "peer %s (inbound, route-refresh)",
2592 rmap_name
, peer
->host
);
2593 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2599 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2603 if (update
&& route_update
&& peer
->status
== Established
)
2605 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2606 PEER_FLAG_SOFT_RECONFIG
))
2608 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2609 zlog_debug("Processing route_map %s update on "
2610 "peer %s (import, soft-reconfig)",
2611 rmap_name
, peer
->host
);
2613 bgp_soft_reconfig_in (peer
, afi
, safi
);
2615 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2616 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2618 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2619 zlog_debug("Processing route_map %s update on "
2620 "peer %s (import, route-refresh)",
2621 rmap_name
, peer
->host
);
2622 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2624 /* DD: Else, what else do we do ? Reset peer ? */
2629 * For outbound, unsuppress and default-originate map change (content or
2630 * map created), merely update the "config" here, the actual route
2631 * announcement happens at the group level.
2633 if (filter
->map
[RMAP_OUT
].name
&&
2634 (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
2635 filter
->map
[RMAP_OUT
].map
= map
;
2637 if (filter
->usmap
.name
&&
2638 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
2639 filter
->usmap
.map
= map
;
2641 if (peer
->default_rmap
[afi
][safi
].name
&&
2642 (strcmp (rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
2643 peer
->default_rmap
[afi
][safi
].map
= map
;
2647 bgp_route_map_update_peer_group(const char *rmap_name
, struct route_map
*map
,
2650 struct peer_group
*group
;
2651 struct listnode
*node
, *nnode
;
2652 struct bgp_filter
*filter
;
2659 /* All the peers have been updated correctly already. This is
2660 * just updating the placeholder data. No real update required.
2662 for (ALL_LIST_ELEMENTS (bgp
->group
, node
, nnode
, group
))
2663 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2664 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2666 filter
= &group
->conf
->filter
[afi
][safi
];
2668 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++)
2670 if ((filter
->map
[direct
].name
) &&
2671 (strcmp(rmap_name
, filter
->map
[direct
].name
) == 0))
2672 filter
->map
[direct
].map
= map
;
2675 if (filter
->usmap
.name
&&
2676 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
2677 filter
->usmap
.map
= map
;
2682 * Note that if an extreme number (tens of thousands) of route-maps are in use
2683 * and if bgp has an extreme number of peers, network statements, etc then this
2684 * function can consume a lot of cycles. This is due to this function being
2685 * called for each route-map and within this function we walk the list of peers,
2686 * network statements, etc looking to see if they use this route-map.
2689 bgp_route_map_process_update (struct bgp
*bgp
, const char *rmap_name
, int route_update
)
2695 struct bgp_node
*bn
;
2696 struct bgp_static
*bgp_static
;
2697 struct listnode
*node
, *nnode
;
2698 struct route_map
*map
;
2699 char buf
[INET6_ADDRSTRLEN
];
2701 map
= route_map_lookup_by_name (rmap_name
);
2703 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
2706 /* Ignore dummy peer-group structure */
2707 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2710 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2711 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2713 /* Ignore inactive AFI/SAFI */
2714 if (! peer
->afc
[afi
][safi
])
2717 /* process in/out/import/export/default-orig route-maps */
2718 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
, safi
, route_update
);
2722 /* for outbound/default-orig route-maps, process for groups */
2723 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
2726 /* update peer-group config (template) */
2727 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
2729 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2730 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2732 /* For table route-map updates. */
2733 if (bgp
->table_map
[afi
][safi
].name
&&
2734 (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
) == 0))
2736 bgp
->table_map
[afi
][safi
].map
= map
;
2738 if (BGP_DEBUG (zebra
, ZEBRA
))
2739 zlog_debug("Processing route_map %s update on "
2740 "table map", rmap_name
);
2742 bgp_zebra_announce_table(bgp
, afi
, safi
);
2745 /* For network route-map updates. */
2746 for (bn
= bgp_table_top (bgp
->route
[afi
][safi
]); bn
; bn
= bgp_route_next (bn
))
2747 if ((bgp_static
= bn
->info
) != NULL
)
2749 if (bgp_static
->rmap
.name
&&
2750 (strcmp(rmap_name
, bgp_static
->rmap
.name
) == 0))
2752 bgp_static
->rmap
.map
= map
;
2755 if (!bgp_static
->backdoor
)
2757 if (bgp_debug_zebra(&bn
->p
))
2758 zlog_debug("Processing route_map %s update on "
2759 "static route %s", rmap_name
,
2760 inet_ntop (bn
->p
.family
, &bn
->p
.u
.prefix
,
2761 buf
, INET6_ADDRSTRLEN
));
2762 bgp_static_update (bgp
, &bn
->p
, bgp_static
, afi
, safi
);
2768 /* For redistribute route-map updates. */
2769 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2770 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
2772 struct list
*red_list
;
2773 struct listnode
*node
;
2774 struct bgp_redist
*red
;
2776 red_list
= bgp
->redist
[afi
][i
];
2780 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
2782 if (red
->rmap
.name
&&
2783 (strcmp(rmap_name
, red
->rmap
.name
) == 0))
2785 red
->rmap
.map
= map
;
2789 if (BGP_DEBUG (zebra
, ZEBRA
))
2790 zlog_debug("Processing route_map %s update on "
2791 "redistributed routes", rmap_name
);
2793 bgp_redistribute_resend (bgp
, afi
, i
, red
->instance
);
2801 bgp_route_map_process_update_cb (char *rmap_name
)
2803 struct listnode
*node
, *nnode
;
2806 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2807 bgp_route_map_process_update(bgp
, rmap_name
, 1);
2810 zlog_debug("%s: calling vnc_routemap_update", __func__
);
2811 vnc_routemap_update(bgp
, __func__
);
2817 bgp_route_map_update_timer(struct thread
*thread
)
2819 bm
->t_rmap_update
= NULL
;
2821 route_map_walk_update_list(bgp_route_map_process_update_cb
);
2827 bgp_route_map_mark_update (const char *rmap_name
)
2829 if (bm
->t_rmap_update
== NULL
)
2831 struct listnode
*node
, *nnode
;
2834 /* rmap_update_timer of 0 means don't do route updates */
2835 if (bm
->rmap_update_timer
)
2838 thread_add_timer(bm
->master
, bgp_route_map_update_timer
, NULL
,
2839 bm
->rmap_update_timer
);
2841 /* Signal the groups that a route-map update event has started */
2842 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2843 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
, 1, 1);
2847 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2848 bgp_route_map_process_update(bgp
, rmap_name
, 0);
2850 zlog_debug("%s: calling vnc_routemap_update", __func__
);
2851 vnc_routemap_update(bgp
, __func__
);
2858 bgp_route_map_add (const char *rmap_name
)
2860 if (route_map_mark_updated(rmap_name
, 0) == 0)
2861 bgp_route_map_mark_update(rmap_name
);
2863 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
2867 bgp_route_map_delete (const char *rmap_name
)
2869 if (route_map_mark_updated(rmap_name
, 1) == 0)
2870 bgp_route_map_mark_update(rmap_name
);
2872 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
2876 bgp_route_map_event (route_map_event_t event
, const char *rmap_name
)
2878 if (route_map_mark_updated(rmap_name
, 0) == 0)
2879 bgp_route_map_mark_update(rmap_name
);
2881 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
2887 "match peer <A.B.C.D|X:X::X:X>",
2889 "Match peer address\n"
2890 "IP address of peer\n"
2891 "IPv6 address of peer\n")
2894 return bgp_route_match_add (vty
, "peer", argv
[idx_ip
]->arg
,
2895 RMAP_EVENT_MATCH_ADDED
);
2898 DEFUN (match_peer_local
,
2899 match_peer_local_cmd
,
2902 "Match peer address\n"
2903 "Static or Redistributed routes\n")
2905 return bgp_route_match_add (vty
, "peer", "local",
2906 RMAP_EVENT_MATCH_DELETED
);
2909 DEFUN (no_match_peer
,
2911 "no match peer [<local|A.B.C.D|X:X::X:X>]",
2914 "Match peer address\n"
2915 "Static or Redistributed routes\n"
2916 "IP address of peer\n"
2917 "IPv6 address of peer\n")
2921 if (argc
<= idx_peer
)
2922 return bgp_route_match_delete (vty
, "peer", NULL
,
2923 RMAP_EVENT_MATCH_DELETED
);
2924 return bgp_route_match_delete (vty
, "peer", argv
[idx_peer
]->arg
,
2925 RMAP_EVENT_MATCH_DELETED
);
2929 /* match probability */
2930 DEFUN (match_probability
,
2931 match_probability_cmd
,
2932 "match probability (0-100)",
2934 "Match portion of routes defined by percentage value\n"
2935 "Percentage of routes\n")
2938 return bgp_route_match_add (vty
, "probability", argv
[idx_number
]->arg
,
2939 RMAP_EVENT_MATCH_ADDED
);
2943 DEFUN (no_match_probability
,
2944 no_match_probability_cmd
,
2945 "no match probability [(1-99)]",
2948 "Match portion of routes defined by percentage value\n"
2949 "Percentage of routes\n")
2952 if (argc
<= idx_number
)
2953 return bgp_route_match_delete (vty
, "probability", NULL
,
2954 RMAP_EVENT_MATCH_DELETED
);
2955 return bgp_route_match_delete (vty
, "probability", argv
[idx_number
]->arg
,
2956 RMAP_EVENT_MATCH_DELETED
);
2960 DEFUN (match_ip_route_source
,
2961 match_ip_route_source_cmd
,
2962 "match ip route-source <(1-199)|(1300-2699)|WORD>",
2965 "Match advertising source address of route\n"
2966 "IP access-list number\n"
2967 "IP access-list number (expanded range)\n"
2968 "IP standard access-list name\n")
2971 return bgp_route_match_add (vty
, "ip route-source", argv
[idx_acl
]->arg
,
2972 RMAP_EVENT_FILTER_ADDED
);
2976 DEFUN (no_match_ip_route_source
,
2977 no_match_ip_route_source_cmd
,
2978 "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
2982 "Match advertising source address of route\n"
2983 "IP access-list number\n"
2984 "IP access-list number (expanded range)\n"
2985 "IP standard access-list name\n")
2988 if (argc
<= idx_number
)
2989 return bgp_route_match_delete (vty
, "ip route-source",
2990 NULL
, RMAP_EVENT_FILTER_DELETED
);
2991 return bgp_route_match_delete (vty
, "ip route-source",
2992 argv
[idx_number
]->arg
, RMAP_EVENT_FILTER_DELETED
);
2996 DEFUN (match_ip_route_source_prefix_list
,
2997 match_ip_route_source_prefix_list_cmd
,
2998 "match ip route-source prefix-list WORD",
3001 "Match advertising source address of route\n"
3002 "Match entries of prefix-lists\n"
3003 "IP prefix-list name\n")
3006 return bgp_route_match_add (vty
, "ip route-source prefix-list",
3007 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3011 DEFUN (no_match_ip_route_source_prefix_list
,
3012 no_match_ip_route_source_prefix_list_cmd
,
3013 "no match ip route-source prefix-list [WORD]",
3017 "Match advertising source address of route\n"
3018 "Match entries of prefix-lists\n"
3019 "IP prefix-list name\n")
3022 if (argc
<= idx_word
)
3023 return bgp_route_match_delete (vty
, "ip route-source prefix-list",
3024 NULL
, RMAP_EVENT_PLIST_DELETED
);
3025 return bgp_route_match_delete (vty
, "ip route-source prefix-list",
3026 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_DELETED
);
3030 DEFUN (match_local_pref
,
3031 match_local_pref_cmd
,
3032 "match local-preference (0-4294967295)",
3034 "Match local-preference of route\n"
3038 return bgp_route_match_add (vty
, "local-preference", argv
[idx_number
]->arg
,
3039 RMAP_EVENT_MATCH_ADDED
);
3043 DEFUN (no_match_local_pref
,
3044 no_match_local_pref_cmd
,
3045 "no match local-preference [(0-4294967295)]",
3048 "Match local preference of route\n"
3049 "Local preference value\n")
3051 int idx_localpref
= 3;
3052 if (argc
<= idx_localpref
)
3053 return bgp_route_match_delete (vty
, "local-preference",
3054 NULL
, RMAP_EVENT_MATCH_DELETED
);
3055 return bgp_route_match_delete (vty
, "local-preference",
3056 argv
[idx_localpref
]->arg
,
3057 RMAP_EVENT_MATCH_DELETED
);
3061 DEFUN (match_community
,
3062 match_community_cmd
,
3063 "match community <(1-99)|(100-500)|WORD>",
3065 "Match BGP community list\n"
3066 "Community-list number (standard)\n"
3067 "Community-list number (expanded)\n"
3068 "Community-list name\n")
3070 int idx_comm_list
= 2;
3071 return bgp_route_match_add (vty
, "community", argv
[idx_comm_list
]->arg
,
3072 RMAP_EVENT_CLIST_ADDED
);
3075 DEFUN (match_community_exact
,
3076 match_community_exact_cmd
,
3077 "match community <(1-99)|(100-500)|WORD> exact-match",
3079 "Match BGP community list\n"
3080 "Community-list number (standard)\n"
3081 "Community-list number (expanded)\n"
3082 "Community-list name\n"
3083 "Do exact matching of communities\n")
3085 int idx_comm_list
= 2;
3089 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3090 strlen (argv
[idx_comm_list
]->arg
) + strlen ("exact-match") + 2);
3092 sprintf (argstr
, "%s exact-match", argv
[idx_comm_list
]->arg
);
3094 ret
= bgp_route_match_add (vty
, "community", argstr
,
3095 RMAP_EVENT_CLIST_ADDED
);
3097 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3102 DEFUN (no_match_community
,
3103 no_match_community_cmd
,
3104 "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
3107 "Match BGP community list\n"
3108 "Community-list number (standard)\n"
3109 "Community-list number (expanded)\n"
3110 "Community-list name\n"
3111 "Do exact matching of communities\n")
3113 return bgp_route_match_delete (vty
, "community", NULL
,
3114 RMAP_EVENT_CLIST_DELETED
);
3119 DEFUN (match_ecommunity
,
3120 match_ecommunity_cmd
,
3121 "match extcommunity <(1-99)|(100-500)|WORD>",
3123 "Match BGP/VPN extended community list\n"
3124 "Extended community-list number (standard)\n"
3125 "Extended community-list number (expanded)\n"
3126 "Extended community-list name\n")
3128 int idx_comm_list
= 2;
3129 return bgp_route_match_add (vty
, "extcommunity", argv
[idx_comm_list
]->arg
,
3130 RMAP_EVENT_ECLIST_ADDED
);
3134 DEFUN (no_match_ecommunity
,
3135 no_match_ecommunity_cmd
,
3136 "no match extcommunity [<(1-99)|(100-500)|WORD>]",
3139 "Match BGP/VPN extended community list\n"
3140 "Extended community-list number (standard)\n"
3141 "Extended community-list number (expanded)\n"
3142 "Extended community-list name\n")
3144 return bgp_route_match_delete (vty
, "extcommunity", NULL
,
3145 RMAP_EVENT_ECLIST_DELETED
);
3149 DEFUN (match_aspath
,
3151 "match as-path WORD",
3153 "Match BGP AS path list\n"
3154 "AS path access-list name\n")
3157 return bgp_route_match_add (vty
, "as-path", argv
[idx_word
]->arg
,
3158 RMAP_EVENT_ASLIST_ADDED
);
3162 DEFUN (no_match_aspath
,
3163 no_match_aspath_cmd
,
3164 "no match as-path [WORD]",
3167 "Match BGP AS path list\n"
3168 "AS path access-list name\n")
3170 return bgp_route_match_delete (vty
, "as-path", NULL
,
3171 RMAP_EVENT_ASLIST_DELETED
);
3175 DEFUN (match_origin
,
3177 "match origin <egp|igp|incomplete>",
3182 "unknown heritage\n")
3185 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
3186 return bgp_route_match_add (vty
, "origin", "igp",
3187 RMAP_EVENT_MATCH_ADDED
);
3188 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
3189 return bgp_route_match_add (vty
, "origin", "egp",
3190 RMAP_EVENT_MATCH_ADDED
);
3191 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3192 return bgp_route_match_add (vty
, "origin", "incomplete",
3193 RMAP_EVENT_MATCH_ADDED
);
3199 DEFUN (no_match_origin
,
3200 no_match_origin_cmd
,
3201 "no match origin [<egp|igp|incomplete>]",
3207 "unknown heritage\n")
3209 return bgp_route_match_delete (vty
, "origin", NULL
,
3210 RMAP_EVENT_MATCH_DELETED
);
3213 DEFUN (set_ip_nexthop_peer
,
3214 set_ip_nexthop_peer_cmd
,
3215 "set ip next-hop peer-address",
3218 "Next hop address\n"
3219 "Use peer address (for BGP only)\n")
3221 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3222 "ip next-hop", "peer-address");
3225 DEFUN (set_ip_nexthop_unchanged
,
3226 set_ip_nexthop_unchanged_cmd
,
3227 "set ip next-hop unchanged",
3230 "Next hop address\n"
3231 "Don't modify existing Next hop address\n")
3233 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3234 "ip next-hop", "unchanged");
3238 DEFUN (set_local_pref
,
3240 "set local-preference (0-4294967295)",
3242 "BGP local preference path attribute\n"
3243 "Preference value\n")
3246 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3247 "local-preference", argv
[idx_number
]->arg
);
3251 DEFUN (no_set_local_pref
,
3252 no_set_local_pref_cmd
,
3253 "no set local-preference [(0-4294967295)]",
3256 "BGP local preference path attribute\n"
3257 "Preference value\n")
3259 int idx_localpref
= 3;
3260 if (argc
<= idx_localpref
)
3261 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3262 "local-preference", NULL
);
3263 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3264 "local-preference", argv
[idx_localpref
]->arg
);
3270 "set weight (0-4294967295)",
3272 "BGP weight for routing table\n"
3276 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "weight",
3277 argv
[idx_number
]->arg
);
3281 DEFUN (no_set_weight
,
3283 "no set weight [(0-4294967295)]",
3286 "BGP weight for routing table\n"
3290 if (argc
<= idx_weight
)
3291 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3293 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
), "weight",
3294 argv
[idx_weight
]->arg
);
3298 DEFUN (set_aspath_prepend_asn
,
3299 set_aspath_prepend_asn_cmd
,
3300 "set as-path prepend (1-4294967295)...",
3302 "Transform BGP AS_PATH attribute\n"
3303 "Prepend to the as-path\n"
3310 str
= argv_concat (argv
, argc
, idx_asn
);
3311 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3312 "as-path prepend", str
);
3313 XFREE (MTYPE_TMP
, str
);
3318 DEFUN (set_aspath_prepend_lastas
,
3319 set_aspath_prepend_lastas_cmd
,
3320 "set as-path prepend last-as (1-10)",
3322 "Transform BGP AS_PATH attribute\n"
3323 "Prepend to the as-path\n"
3324 "Use the peer's AS-number\n"
3325 "Number of times to insert")
3327 return set_aspath_prepend_asn (self
, vty
, argc
, argv
);
3330 DEFUN (no_set_aspath_prepend
,
3331 no_set_aspath_prepend_cmd
,
3332 "no set as-path prepend [(1-4294967295)]",
3335 "Transform BGP AS_PATH attribute\n"
3336 "Prepend to the as-path\n"
3343 str
= argv_concat (argv
, argc
, idx_asn
);
3344 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3345 "as-path prepend", str
);
3346 XFREE (MTYPE_TMP
, str
);
3351 DEFUN (set_aspath_exclude
,
3352 set_aspath_exclude_cmd
,
3353 "set as-path exclude (1-4294967295)...",
3355 "Transform BGP AS-path attribute\n"
3356 "Exclude from the as-path\n"
3363 str
= argv_concat (argv
, argc
, idx_asn
);
3364 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3365 "as-path exclude", str
);
3366 XFREE (MTYPE_TMP
, str
);
3370 DEFUN (no_set_aspath_exclude
,
3371 no_set_aspath_exclude_cmd
,
3372 "no set as-path exclude (1-4294967295)...",
3375 "Transform BGP AS_PATH attribute\n"
3376 "Exclude from the as-path\n"
3383 str
= argv_concat (argv
, argc
, idx_asn
);
3384 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3385 "as-path exclude", str
);
3386 XFREE (MTYPE_TMP
, str
);
3391 DEFUN (set_community
,
3393 "set community AA:NN...",
3395 "BGP community attribute\n"
3403 struct community
*com
= NULL
;
3408 b
= buffer_new (1024);
3410 for (i
= idx_aa_nn
; i
< argc
; i
++)
3412 if (strncmp (argv
[i
]->arg
, "additive", strlen (argv
[i
]->arg
)) == 0)
3419 buffer_putc (b
, ' ');
3423 if (strncmp (argv
[i
]->arg
, "internet", strlen (argv
[i
]->arg
)) == 0)
3425 buffer_putstr (b
, "internet");
3428 if (strncmp (argv
[i
]->arg
, "local-AS", strlen (argv
[i
]->arg
)) == 0)
3430 buffer_putstr (b
, "local-AS");
3433 if (strncmp (argv
[i
]->arg
, "no-a", strlen ("no-a")) == 0
3434 && strncmp (argv
[i
]->arg
, "no-advertise", strlen (argv
[i
]->arg
)) == 0)
3436 buffer_putstr (b
, "no-advertise");
3439 if (strncmp (argv
[i
]->arg
, "no-e", strlen ("no-e"))== 0
3440 && strncmp (argv
[i
]->arg
, "no-export", strlen (argv
[i
]->arg
)) == 0)
3442 buffer_putstr (b
, "no-export");
3445 buffer_putstr (b
, argv
[i
]->arg
);
3447 buffer_putc (b
, '\0');
3449 /* Fetch result string then compile it to communities attribute. */
3450 str
= buffer_getstr (b
);
3455 com
= community_str2com (str
);
3456 XFREE (MTYPE_TMP
, str
);
3459 /* Can't compile user input into communities attribute. */
3462 vty_out (vty
, "%% Malformed communities attribute%s", VTY_NEWLINE
);
3466 /* Set communites attribute string. */
3467 str
= community_str (com
);
3471 argstr
= XCALLOC (MTYPE_TMP
, strlen (str
) + strlen (" additive") + 1);
3472 strcpy (argstr
, str
);
3473 strcpy (argstr
+ strlen (str
), " additive");
3474 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3475 "community", argstr
);
3476 XFREE (MTYPE_TMP
, argstr
);
3479 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3482 community_free (com
);
3487 DEFUN (set_community_none
,
3488 set_community_none_cmd
,
3489 "set community none",
3491 "BGP community attribute\n"
3492 "No community attribute\n")
3494 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "community",
3498 DEFUN (no_set_community
,
3499 no_set_community_cmd
,
3500 "no set community AA:NN...",
3503 "BGP community attribute\n"
3506 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3512 DEFUN (set_community_delete
,
3513 set_community_delete_cmd
,
3514 "set comm-list <(1-99)|(100-500)|WORD> delete",
3516 "set BGP community list (for deletion)\n"
3517 "Community-list number (standard)\n"
3518 "Community-list number (expanded)\n"
3519 "Community-list name\n"
3520 "Delete matching communities\n")
3522 int idx_comm_list
= 2;
3525 str
= XCALLOC (MTYPE_TMP
, strlen (argv
[idx_comm_list
]->arg
) + strlen (" delete") + 1);
3526 strcpy (str
, argv
[idx_comm_list
]->arg
);
3527 strcpy (str
+ strlen (argv
[idx_comm_list
]->arg
), " delete");
3529 generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "comm-list", str
);
3531 XFREE (MTYPE_TMP
, str
);
3535 DEFUN (no_set_community_delete
,
3536 no_set_community_delete_cmd
,
3537 "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
3540 "set BGP community list (for deletion)\n"
3541 "Community-list number (standard)\n"
3542 "Community-list number (expanded)\n"
3543 "Community-list name\n"
3544 "Delete matching communities\n")
3546 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3551 DEFUN (set_ecommunity_rt
,
3552 set_ecommunity_rt_cmd
,
3553 "set extcommunity rt ASN:nn_or_IP-address:nn...",
3555 "BGP extended community attribute\n"
3556 "Route Target extended community\n"
3557 "VPN extended community\n")
3563 str
= argv_concat (argv
, argc
, idx_asn_nn
);
3564 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3565 "extcommunity rt", str
);
3566 XFREE (MTYPE_TMP
, str
);
3571 DEFUN (no_set_ecommunity_rt
,
3572 no_set_ecommunity_rt_cmd
,
3573 "no set extcommunity rt ASN:nn_or_IP-address:nn...",
3576 "BGP extended community attribute\n"
3577 "Route Target extended community\n"
3578 "VPN extended community\n")
3580 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3581 "extcommunity rt", NULL
);
3585 DEFUN (set_ecommunity_soo
,
3586 set_ecommunity_soo_cmd
,
3587 "set extcommunity soo ASN:nn_or_IP-address:nn...",
3589 "BGP extended community attribute\n"
3590 "Site-of-Origin extended community\n"
3591 "VPN extended community\n")
3597 str
= argv_concat (argv
, argc
, idx_asn_nn
);
3598 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3599 "extcommunity soo", str
);
3600 XFREE (MTYPE_TMP
, str
);
3605 DEFUN (no_set_ecommunity_soo
,
3606 no_set_ecommunity_soo_cmd
,
3607 "no set extcommunity soo ASN:nn_or_IP-address:nn...",
3610 "BGP extended community attribute\n"
3611 "Site-of-Origin extended community\n"
3612 "VPN extended community\n")
3614 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3615 "extcommunity soo", NULL
);
3621 "set origin <egp|igp|incomplete>",
3626 "unknown heritage\n")
3629 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
3630 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
3632 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
3633 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
3635 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3636 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
3643 DEFUN (no_set_origin
,
3645 "no set origin [<egp|igp|incomplete>]",
3651 "unknown heritage\n")
3653 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
), "origin",
3658 DEFUN (set_atomic_aggregate
,
3659 set_atomic_aggregate_cmd
,
3660 "set atomic-aggregate",
3662 "BGP atomic aggregate attribute\n" )
3664 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3665 "atomic-aggregate", NULL
);
3668 DEFUN (no_set_atomic_aggregate
,
3669 no_set_atomic_aggregate_cmd
,
3670 "no set atomic-aggregate",
3673 "BGP atomic aggregate attribute\n" )
3675 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3676 "atomic-aggregate", NULL
);
3679 DEFUN (set_aggregator_as
,
3680 set_aggregator_as_cmd
,
3681 "set aggregator as (1-4294967295) A.B.C.D",
3683 "BGP aggregator attribute\n"
3684 "AS number of aggregator\n"
3686 "IP address of aggregator\n")
3691 struct in_addr address
;
3694 ret
= inet_aton (argv
[idx_ipv4
]->arg
, &address
);
3697 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
3701 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3702 strlen (argv
[idx_number
]->arg
) + strlen (argv
[idx_ipv4
]->arg
) + 2);
3704 sprintf (argstr
, "%s %s", argv
[idx_number
]->arg
, argv
[idx_ipv4
]->arg
);
3706 ret
= generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3707 "aggregator as", argstr
);
3709 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3715 DEFUN (no_set_aggregator_as
,
3716 no_set_aggregator_as_cmd
,
3717 "no set aggregator as [(1-4294967295) A.B.C.D]",
3720 "BGP aggregator attribute\n"
3721 "AS number of aggregator\n"
3723 "IP address of aggregator\n")
3728 struct in_addr address
;
3731 if (argc
<= idx_asn
)
3732 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3733 "aggregator as", NULL
);
3735 ret
= inet_aton (argv
[idx_ip
]->arg
, &address
);
3738 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
3742 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3743 strlen (argv
[idx_asn
]->arg
) + strlen (argv
[idx_ip
]->arg
) + 2);
3745 sprintf (argstr
, "%s %s", argv
[idx_asn
]->arg
, argv
[idx_ip
]->arg
);
3747 ret
= generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3748 "aggregator as", argstr
);
3750 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3755 DEFUN (match_ipv6_next_hop
,
3756 match_ipv6_next_hop_cmd
,
3757 "match ipv6 next-hop X:X::X:X",
3760 "Match IPv6 next-hop address of route\n"
3761 "IPv6 address of next hop\n")
3764 return bgp_route_match_add (vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
3765 RMAP_EVENT_MATCH_ADDED
);
3768 DEFUN (no_match_ipv6_next_hop
,
3769 no_match_ipv6_next_hop_cmd
,
3770 "no match ipv6 next-hop X:X::X:X",
3774 "Match IPv6 next-hop address of route\n"
3775 "IPv6 address of next hop\n")
3778 return bgp_route_match_delete (vty
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
3779 RMAP_EVENT_MATCH_DELETED
);
3783 DEFUN (set_ipv6_nexthop_peer
,
3784 set_ipv6_nexthop_peer_cmd
,
3785 "set ipv6 next-hop peer-address",
3788 "Next hop address\n"
3789 "Use peer address (for BGP only)\n")
3791 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3792 "ipv6 next-hop peer-address", NULL
);
3795 DEFUN (no_set_ipv6_nexthop_peer
,
3796 no_set_ipv6_nexthop_peer_cmd
,
3797 "no set ipv6 next-hop peer-address",
3801 "IPv6 next-hop address\n"
3802 "Use peer address (for BGP only)\n")
3804 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3805 "ipv6 next-hop peer-address", NULL
);
3808 DEFUN (set_ipv6_nexthop_prefer_global
,
3809 set_ipv6_nexthop_prefer_global_cmd
,
3810 "set ipv6 next-hop prefer-global",
3813 "IPv6 next-hop address\n"
3814 "Prefer global over link-local if both exist\n")
3816 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3817 "ipv6 next-hop prefer-global", NULL
);;
3820 DEFUN (no_set_ipv6_nexthop_prefer_global
,
3821 no_set_ipv6_nexthop_prefer_global_cmd
,
3822 "no set ipv6 next-hop prefer-global",
3826 "IPv6 next-hop address\n"
3827 "Prefer global over link-local if both exist\n")
3829 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3830 "ipv6 next-hop prefer-global", NULL
);
3833 DEFUN (set_ipv6_nexthop_global
,
3834 set_ipv6_nexthop_global_cmd
,
3835 "set ipv6 next-hop global X:X::X:X",
3838 "IPv6 next-hop address\n"
3839 "IPv6 global address\n"
3840 "IPv6 address of next hop\n")
3843 struct in6_addr addr
;
3846 ret
= inet_pton (AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
3849 vty_out (vty
, "%% Malformed nexthop address%s", VTY_NEWLINE
);
3852 if (IN6_IS_ADDR_UNSPECIFIED(&addr
) ||
3853 IN6_IS_ADDR_LOOPBACK(&addr
) ||
3854 IN6_IS_ADDR_MULTICAST(&addr
) ||
3855 IN6_IS_ADDR_LINKLOCAL(&addr
))
3857 vty_out (vty
, "%% Invalid global nexthop address%s", VTY_NEWLINE
);
3861 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3862 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
3866 DEFUN (no_set_ipv6_nexthop_global
,
3867 no_set_ipv6_nexthop_global_cmd
,
3868 "no set ipv6 next-hop global X:X::X:X",
3872 "IPv6 next-hop address\n"
3873 "IPv6 global address\n"
3874 "IPv6 address of next hop\n")
3877 if (argc
<= idx_ipv6
)
3878 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3879 "ipv6 next-hop global", NULL
);
3880 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3881 "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
3884 DEFUN (set_vpnv4_nexthop
,
3885 set_vpnv4_nexthop_cmd
,
3886 "set vpnv4 next-hop A.B.C.D",
3888 "VPNv4 information\n"
3889 "VPNv4 next-hop address\n"
3890 "IP address of next hop\n")
3893 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3894 "vpnv4 next-hop", argv
[idx_ipv4
]->arg
);
3898 DEFUN (no_set_vpnv4_nexthop
,
3899 no_set_vpnv4_nexthop_cmd
,
3900 "no set vpnv4 next-hop [A.B.C.D]",
3903 "VPNv4 information\n"
3904 "VPNv4 next-hop address\n"
3905 "IP address of next hop\n")
3908 if (argc
<= idx_ipv4
)
3909 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3910 "vpnv4 next-hop", NULL
);
3911 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3912 "vpnv4 next-hop", argv
[idx_ipv4
]->arg
);
3916 DEFUN (set_originator_id
,
3917 set_originator_id_cmd
,
3918 "set originator-id A.B.C.D",
3920 "BGP originator ID attribute\n"
3921 "IP address of originator\n")
3924 return generic_set_add (vty
, VTY_GET_CONTEXT(route_map_index
),
3925 "originator-id", argv
[idx_ipv4
]->arg
);
3929 DEFUN (no_set_originator_id
,
3930 no_set_originator_id_cmd
,
3931 "no set originator-id [A.B.C.D]",
3934 "BGP originator ID attribute\n"
3935 "IP address of originator\n")
3939 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3940 "originator-id", NULL
);
3941 return generic_set_delete (vty
, VTY_GET_CONTEXT(route_map_index
),
3942 "originator-id", argv
[idx_id
]->arg
);
3946 /* Initialization of route map. */
3948 bgp_route_map_init (void)
3952 route_map_add_hook (bgp_route_map_add
);
3953 route_map_delete_hook (bgp_route_map_delete
);
3954 route_map_event_hook (bgp_route_map_event
);
3956 route_map_match_interface_hook (generic_match_add
);
3957 route_map_no_match_interface_hook (generic_match_delete
);
3959 route_map_match_ip_address_hook (generic_match_add
);
3960 route_map_no_match_ip_address_hook (generic_match_delete
);
3962 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
3963 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
3965 route_map_match_ip_next_hop_hook (generic_match_add
);
3966 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
3968 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
3969 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
3971 route_map_match_ipv6_address_hook (generic_match_add
);
3972 route_map_no_match_ipv6_address_hook (generic_match_delete
);
3974 route_map_match_ipv6_address_prefix_list_hook (generic_match_add
);
3975 route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete
);
3977 route_map_match_metric_hook (generic_match_add
);
3978 route_map_no_match_metric_hook (generic_match_delete
);
3980 route_map_match_tag_hook (generic_match_add
);
3981 route_map_no_match_tag_hook (generic_match_delete
);
3983 route_map_set_ip_nexthop_hook (generic_set_add
);
3984 route_map_no_set_ip_nexthop_hook (generic_set_delete
);
3986 route_map_set_ipv6_nexthop_local_hook (generic_set_add
);
3987 route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete
);
3989 route_map_set_metric_hook (generic_set_add
);
3990 route_map_no_set_metric_hook (generic_set_delete
);
3992 route_map_set_tag_hook (generic_set_add
);
3993 route_map_no_set_tag_hook (generic_set_delete
);
3995 route_map_install_match (&route_match_peer_cmd
);
3996 route_map_install_match (&route_match_local_pref_cmd
);
3997 route_map_install_match (&route_match_ip_address_cmd
);
3998 route_map_install_match (&route_match_ip_next_hop_cmd
);
3999 route_map_install_match (&route_match_ip_route_source_cmd
);
4000 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
4001 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
4002 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd
);
4003 route_map_install_match (&route_match_aspath_cmd
);
4004 route_map_install_match (&route_match_community_cmd
);
4005 route_map_install_match (&route_match_ecommunity_cmd
);
4006 route_map_install_match (&route_match_local_pref_cmd
);
4007 route_map_install_match (&route_match_metric_cmd
);
4008 route_map_install_match (&route_match_origin_cmd
);
4009 route_map_install_match (&route_match_probability_cmd
);
4010 route_map_install_match (&route_match_interface_cmd
);
4011 route_map_install_match (&route_match_tag_cmd
);
4013 route_map_install_set (&route_set_ip_nexthop_cmd
);
4014 route_map_install_set (&route_set_local_pref_cmd
);
4015 route_map_install_set (&route_set_weight_cmd
);
4016 route_map_install_set (&route_set_metric_cmd
);
4017 route_map_install_set (&route_set_aspath_prepend_cmd
);
4018 route_map_install_set (&route_set_aspath_exclude_cmd
);
4019 route_map_install_set (&route_set_origin_cmd
);
4020 route_map_install_set (&route_set_atomic_aggregate_cmd
);
4021 route_map_install_set (&route_set_aggregator_as_cmd
);
4022 route_map_install_set (&route_set_community_cmd
);
4023 route_map_install_set (&route_set_community_delete_cmd
);
4024 route_map_install_set (&route_set_vpnv4_nexthop_cmd
);
4025 route_map_install_set (&route_set_originator_id_cmd
);
4026 route_map_install_set (&route_set_ecommunity_rt_cmd
);
4027 route_map_install_set (&route_set_ecommunity_soo_cmd
);
4028 route_map_install_set (&route_set_tag_cmd
);
4030 install_element (RMAP_NODE
, &match_peer_cmd
);
4031 install_element (RMAP_NODE
, &match_peer_local_cmd
);
4032 install_element (RMAP_NODE
, &no_match_peer_cmd
);
4033 install_element (RMAP_NODE
, &match_ip_route_source_cmd
);
4034 install_element (RMAP_NODE
, &no_match_ip_route_source_cmd
);
4035 install_element (RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
4036 install_element (RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
4038 install_element (RMAP_NODE
, &match_aspath_cmd
);
4039 install_element (RMAP_NODE
, &no_match_aspath_cmd
);
4040 install_element (RMAP_NODE
, &match_local_pref_cmd
);
4041 install_element (RMAP_NODE
, &no_match_local_pref_cmd
);
4042 install_element (RMAP_NODE
, &match_community_cmd
);
4043 install_element (RMAP_NODE
, &match_community_exact_cmd
);
4044 install_element (RMAP_NODE
, &no_match_community_cmd
);
4045 install_element (RMAP_NODE
, &match_ecommunity_cmd
);
4046 install_element (RMAP_NODE
, &no_match_ecommunity_cmd
);
4047 install_element (RMAP_NODE
, &match_origin_cmd
);
4048 install_element (RMAP_NODE
, &no_match_origin_cmd
);
4049 install_element (RMAP_NODE
, &match_probability_cmd
);
4050 install_element (RMAP_NODE
, &no_match_probability_cmd
);
4052 install_element (RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
4053 install_element (RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
4054 install_element (RMAP_NODE
, &set_local_pref_cmd
);
4055 install_element (RMAP_NODE
, &no_set_local_pref_cmd
);
4056 install_element (RMAP_NODE
, &set_weight_cmd
);
4057 install_element (RMAP_NODE
, &no_set_weight_cmd
);
4058 install_element (RMAP_NODE
, &set_aspath_prepend_asn_cmd
);
4059 install_element (RMAP_NODE
, &set_aspath_prepend_lastas_cmd
);
4060 install_element (RMAP_NODE
, &set_aspath_exclude_cmd
);
4061 install_element (RMAP_NODE
, &no_set_aspath_prepend_cmd
);
4062 install_element (RMAP_NODE
, &no_set_aspath_exclude_cmd
);
4063 install_element (RMAP_NODE
, &set_origin_cmd
);
4064 install_element (RMAP_NODE
, &no_set_origin_cmd
);
4065 install_element (RMAP_NODE
, &set_atomic_aggregate_cmd
);
4066 install_element (RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
4067 install_element (RMAP_NODE
, &set_aggregator_as_cmd
);
4068 install_element (RMAP_NODE
, &no_set_aggregator_as_cmd
);
4069 install_element (RMAP_NODE
, &set_community_cmd
);
4070 install_element (RMAP_NODE
, &set_community_none_cmd
);
4071 install_element (RMAP_NODE
, &no_set_community_cmd
);
4072 install_element (RMAP_NODE
, &set_community_delete_cmd
);
4073 install_element (RMAP_NODE
, &no_set_community_delete_cmd
);
4074 install_element (RMAP_NODE
, &set_ecommunity_rt_cmd
);
4075 install_element (RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
4076 install_element (RMAP_NODE
, &set_ecommunity_soo_cmd
);
4077 install_element (RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
4078 install_element (RMAP_NODE
, &set_vpnv4_nexthop_cmd
);
4079 install_element (RMAP_NODE
, &no_set_vpnv4_nexthop_cmd
);
4080 install_element (RMAP_NODE
, &set_originator_id_cmd
);
4081 install_element (RMAP_NODE
, &no_set_originator_id_cmd
);
4083 route_map_install_match (&route_match_ipv6_address_cmd
);
4084 route_map_install_match (&route_match_ipv6_next_hop_cmd
);
4085 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd
);
4086 route_map_install_set (&route_set_ipv6_nexthop_global_cmd
);
4087 route_map_install_set (&route_set_ipv6_nexthop_prefer_global_cmd
);
4088 route_map_install_set (&route_set_ipv6_nexthop_local_cmd
);
4089 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd
);
4091 install_element (RMAP_NODE
, &match_ipv6_next_hop_cmd
);
4092 install_element (RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
4093 install_element (RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
4094 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
4095 install_element (RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
4096 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
4097 install_element (RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
4098 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
4102 bgp_route_map_terminate (void)
4104 /* ToDo: Cleanup all the used memory */
4106 route_map_add_hook (NULL
);
4107 route_map_delete_hook (NULL
);
4108 route_map_event_hook (NULL
);