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>
35 # ifdef HAVE_GNU_REGEX
38 # include "regex-gnu.h"
39 # endif /* HAVE_GNU_REGEX */
40 #endif /* HAVE_LIBPCREPOSIX */
42 #include "sockunion.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_attr.h"
49 #include "bgpd/bgp_aspath.h"
50 #include "bgpd/bgp_packet.h"
51 #include "bgpd/bgp_route.h"
52 #include "bgpd/bgp_zebra.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_clist.h"
56 #include "bgpd/bgp_filter.h"
57 #include "bgpd/bgp_mplsvpn.h"
58 #include "bgpd/bgp_ecommunity.h"
59 #include "bgpd/bgp_vty.h"
60 #include "bgpd/bgp_debug.h"
63 # include "bgpd/rfapi/bgp_rfapi_cfg.h"
66 /* Memo of route-map commands.
75 ip route-source : Done
79 ipv6 route-source: (This will not be implemented by bgpd)
80 ipv6 prefix-list : Done
81 length : (This will not be implemented by bgpd)
83 route-type : (This will not be implemented by bgpd)
85 local-preference : Done
87 set as-path prepend : Done
89 automatic-tag : (This will not be implemented by bgpd)
93 default : (This will not be implemented by bgpd)
94 interface : (This will not be implemented by bgpd)
95 ip default : (This will not be implemented by bgpd)
97 ip precedence : (This will not be implemented by bgpd)
98 ip tos : (This will not be implemented by bgpd)
99 level : (This will not be implemented by bgpd)
100 local-preference : Done
102 metric-type : Not yet
109 set ipv6 next-hop global: Done
110 set ipv6 next-hop prefer-global: Done
111 set ipv6 next-hop local : Done
112 set as-path exclude : Done
116 /* generic value manipulation to be shared in multiple rules */
118 #define RMAP_VALUE_SET 0
119 #define RMAP_VALUE_ADD 1
120 #define RMAP_VALUE_SUB 2
130 route_value_match (struct rmap_value
*rv
, u_int32_t value
)
132 if (rv
->variable
== 0 && value
== rv
->value
)
139 route_value_adjust (struct rmap_value
*rv
, u_int32_t current
, struct peer
*peer
)
143 switch (rv
->variable
)
156 if (current
> UINT32_MAX
-value
)
158 return current
+ value
;
160 if (current
<= value
)
162 return current
- value
;
169 route_value_compile (const char *arg
)
171 u_int8_t action
= RMAP_VALUE_SET
, var
= 0;
172 unsigned long larg
= 0;
174 struct rmap_value
*rv
;
178 action
= RMAP_VALUE_ADD
;
181 else if (arg
[0] == '-')
183 action
= RMAP_VALUE_SUB
;
190 larg
= strtoul (arg
, &endptr
, 10);
191 if (*arg
== 0 || *endptr
!= 0 || errno
|| larg
> UINT32_MAX
)
196 if (strcmp(arg
, "rtt") == 0)
202 rv
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof(struct rmap_value
));
213 route_value_free (void *rule
)
215 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
218 /* generic as path object to be shared in multiple rules */
221 route_aspath_compile (const char *arg
)
223 struct aspath
*aspath
;
225 aspath
= aspath_str2aspath (arg
);
232 route_aspath_free (void *rule
)
234 struct aspath
*aspath
= rule
;
235 aspath_free (aspath
);
238 /* 'match peer (A.B.C.D|X:X::X:X)' */
240 /* Compares the peer specified in the 'match peer' clause with the peer
241 received in bgp_info->peer. If it is the same, or if the peer structure
242 received is a peer_group containing it, returns RMAP_MATCH. */
243 static route_map_result_t
244 route_match_peer (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
248 union sockunion su_def
= { .sin
= { .sin_family
= AF_INET
,
249 .sin_addr
.s_addr
= INADDR_ANY
} };
250 struct peer_group
*group
;
252 struct listnode
*node
, *nnode
;
254 if (type
== RMAP_BGP
)
257 peer
= ((struct bgp_info
*) object
)->peer
;
259 if ( ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
) &&
260 ! CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_EXPORT
) )
263 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
264 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
265 if (sockunion_same (su
, &su_def
))
268 if ( CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_NETWORK
) ||
269 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_REDISTRIBUTE
) ||
270 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_DEFAULT
))
277 if (! CHECK_FLAG (peer
->sflags
, PEER_STATUS_GROUP
))
279 if (sockunion_same (su
, &peer
->su
))
287 for (ALL_LIST_ELEMENTS (group
->peer
, node
, nnode
, peer
))
289 if (sockunion_same (su
, &peer
->su
))
299 route_match_peer_compile (const char *arg
)
304 su
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union sockunion
));
306 ret
= str2sockunion (strcmp(arg
, "local") ? arg
: "0.0.0.0", su
);
308 XFREE (MTYPE_ROUTE_MAP_COMPILED
, su
);
315 /* Free route map's compiled `ip address' value. */
317 route_match_peer_free (void *rule
)
319 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
322 /* Route map commands for ip address matching. */
323 struct route_map_rule_cmd route_match_peer_cmd
=
327 route_match_peer_compile
,
328 route_match_peer_free
331 /* `match ip address IP_ACCESS_LIST' */
333 /* Match function should return 1 if match is success else return
335 static route_map_result_t
336 route_match_ip_address (void *rule
, struct prefix
*prefix
,
337 route_map_object_t type
, void *object
)
339 struct access_list
*alist
;
340 /* struct prefix_ipv4 match; */
342 if (type
== RMAP_BGP
)
344 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
348 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
349 RMAP_NOMATCH
: RMAP_MATCH
);
354 /* Route map `ip address' match statement. `arg' should be
357 route_match_ip_address_compile (const char *arg
)
359 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
362 /* Free route map's compiled `ip address' value. */
364 route_match_ip_address_free (void *rule
)
366 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
369 /* Route map commands for ip address matching. */
370 struct route_map_rule_cmd route_match_ip_address_cmd
=
373 route_match_ip_address
,
374 route_match_ip_address_compile
,
375 route_match_ip_address_free
378 /* `match ip next-hop IP_ADDRESS' */
380 /* Match function return 1 if match is success else return zero. */
381 static route_map_result_t
382 route_match_ip_next_hop (void *rule
, struct prefix
*prefix
,
383 route_map_object_t type
, void *object
)
385 struct access_list
*alist
;
386 struct bgp_info
*bgp_info
;
387 struct prefix_ipv4 p
;
389 if (type
== RMAP_BGP
)
393 p
.prefix
= bgp_info
->attr
->nexthop
;
394 p
.prefixlen
= IPV4_MAX_BITLEN
;
396 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
400 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
401 RMAP_NOMATCH
: RMAP_MATCH
);
406 /* Route map `ip next-hop' match statement. `arg' is
409 route_match_ip_next_hop_compile (const char *arg
)
411 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
414 /* Free route map's compiled `ip address' value. */
416 route_match_ip_next_hop_free (void *rule
)
418 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
421 /* Route map commands for ip next-hop matching. */
422 struct route_map_rule_cmd route_match_ip_next_hop_cmd
=
425 route_match_ip_next_hop
,
426 route_match_ip_next_hop_compile
,
427 route_match_ip_next_hop_free
430 /* `match ip route-source ACCESS-LIST' */
432 /* Match function return 1 if match is success else return zero. */
433 static route_map_result_t
434 route_match_ip_route_source (void *rule
, struct prefix
*prefix
,
435 route_map_object_t type
, void *object
)
437 struct access_list
*alist
;
438 struct bgp_info
*bgp_info
;
440 struct prefix_ipv4 p
;
442 if (type
== RMAP_BGP
)
445 peer
= bgp_info
->peer
;
447 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
451 p
.prefix
= peer
->su
.sin
.sin_addr
;
452 p
.prefixlen
= IPV4_MAX_BITLEN
;
454 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
458 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
459 RMAP_NOMATCH
: RMAP_MATCH
);
464 /* Route map `ip route-source' match statement. `arg' is
467 route_match_ip_route_source_compile (const char *arg
)
469 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
472 /* Free route map's compiled `ip address' value. */
474 route_match_ip_route_source_free (void *rule
)
476 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
479 /* Route map commands for ip route-source matching. */
480 struct route_map_rule_cmd route_match_ip_route_source_cmd
=
483 route_match_ip_route_source
,
484 route_match_ip_route_source_compile
,
485 route_match_ip_route_source_free
488 /* `match ip address prefix-list PREFIX_LIST' */
490 static route_map_result_t
491 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
492 route_map_object_t type
, void *object
)
494 struct prefix_list
*plist
;
496 if (type
== RMAP_BGP
)
498 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
502 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
503 RMAP_NOMATCH
: RMAP_MATCH
);
509 route_match_ip_address_prefix_list_compile (const char *arg
)
511 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
515 route_match_ip_address_prefix_list_free (void *rule
)
517 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
520 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
522 "ip address prefix-list",
523 route_match_ip_address_prefix_list
,
524 route_match_ip_address_prefix_list_compile
,
525 route_match_ip_address_prefix_list_free
528 /* `match ip next-hop prefix-list PREFIX_LIST' */
530 static route_map_result_t
531 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
532 route_map_object_t type
, void *object
)
534 struct prefix_list
*plist
;
535 struct bgp_info
*bgp_info
;
536 struct prefix_ipv4 p
;
538 if (type
== RMAP_BGP
)
542 p
.prefix
= bgp_info
->attr
->nexthop
;
543 p
.prefixlen
= IPV4_MAX_BITLEN
;
545 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
549 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
550 RMAP_NOMATCH
: RMAP_MATCH
);
556 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
558 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
562 route_match_ip_next_hop_prefix_list_free (void *rule
)
564 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
567 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
569 "ip next-hop prefix-list",
570 route_match_ip_next_hop_prefix_list
,
571 route_match_ip_next_hop_prefix_list_compile
,
572 route_match_ip_next_hop_prefix_list_free
575 /* `match ip route-source prefix-list PREFIX_LIST' */
577 static route_map_result_t
578 route_match_ip_route_source_prefix_list (void *rule
, struct prefix
*prefix
,
579 route_map_object_t type
, void *object
)
581 struct prefix_list
*plist
;
582 struct bgp_info
*bgp_info
;
584 struct prefix_ipv4 p
;
586 if (type
== RMAP_BGP
)
589 peer
= bgp_info
->peer
;
591 if (! peer
|| sockunion_family (&peer
->su
) != AF_INET
)
595 p
.prefix
= peer
->su
.sin
.sin_addr
;
596 p
.prefixlen
= IPV4_MAX_BITLEN
;
598 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
602 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
603 RMAP_NOMATCH
: RMAP_MATCH
);
609 route_match_ip_route_source_prefix_list_compile (const char *arg
)
611 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
615 route_match_ip_route_source_prefix_list_free (void *rule
)
617 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
620 struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd
=
622 "ip route-source prefix-list",
623 route_match_ip_route_source_prefix_list
,
624 route_match_ip_route_source_prefix_list_compile
,
625 route_match_ip_route_source_prefix_list_free
628 /* `match local-preference LOCAL-PREF' */
630 /* Match function return 1 if match is success else return zero. */
631 static route_map_result_t
632 route_match_local_pref (void *rule
, struct prefix
*prefix
,
633 route_map_object_t type
, void *object
)
635 u_int32_t
*local_pref
;
636 struct bgp_info
*bgp_info
;
638 if (type
== RMAP_BGP
)
643 if (bgp_info
->attr
->local_pref
== *local_pref
)
651 /* Route map `match local-preference' match statement.
652 `arg' is local-pref value */
654 route_match_local_pref_compile (const char *arg
)
656 u_int32_t
*local_pref
;
658 unsigned long tmpval
;
660 /* Locpref value shoud be integer. */
661 if (! all_digit (arg
))
665 tmpval
= strtoul (arg
, &endptr
, 10);
666 if (*endptr
!= '\0' || errno
|| tmpval
> UINT32_MAX
)
669 local_pref
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
674 *local_pref
= tmpval
;
678 /* Free route map's compiled `match local-preference' value. */
680 route_match_local_pref_free (void *rule
)
682 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
685 /* Route map commands for metric matching. */
686 struct route_map_rule_cmd route_match_local_pref_cmd
=
689 route_match_local_pref
,
690 route_match_local_pref_compile
,
691 route_match_local_pref_free
694 /* `match metric METRIC' */
696 /* Match function return 1 if match is success else return zero. */
697 static route_map_result_t
698 route_match_metric (void *rule
, struct prefix
*prefix
,
699 route_map_object_t type
, void *object
)
701 struct rmap_value
*rv
;
702 struct bgp_info
*bgp_info
;
704 if (type
== RMAP_BGP
)
708 return route_value_match(rv
, bgp_info
->attr
->med
);
713 /* Route map commands for metric matching. */
714 struct route_map_rule_cmd route_match_metric_cmd
=
722 /* `match as-path ASPATH' */
724 /* Match function for as-path match. I assume given object is */
725 static route_map_result_t
726 route_match_aspath (void *rule
, struct prefix
*prefix
,
727 route_map_object_t type
, void *object
)
730 struct as_list
*as_list
;
731 struct bgp_info
*bgp_info
;
733 if (type
== RMAP_BGP
)
735 as_list
= as_list_lookup ((char *) rule
);
742 return ((as_list_apply (as_list
, bgp_info
->attr
->aspath
) == AS_FILTER_DENY
) ? RMAP_NOMATCH
: RMAP_MATCH
);
747 /* Compile function for as-path match. */
749 route_match_aspath_compile (const char *arg
)
751 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
754 /* Compile function for as-path match. */
756 route_match_aspath_free (void *rule
)
758 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
761 /* Route map commands for aspath matching. */
762 struct route_map_rule_cmd route_match_aspath_cmd
=
766 route_match_aspath_compile
,
767 route_match_aspath_free
770 /* `match community COMMUNIY' */
771 struct rmap_community
777 /* Match function for community match. */
778 static route_map_result_t
779 route_match_community (void *rule
, struct prefix
*prefix
,
780 route_map_object_t type
, void *object
)
782 struct community_list
*list
;
783 struct bgp_info
*bgp_info
;
784 struct rmap_community
*rcom
;
786 if (type
== RMAP_BGP
)
791 list
= community_list_lookup (bgp_clist
, rcom
->name
, COMMUNITY_LIST_MASTER
);
797 if (community_list_exact_match (bgp_info
->attr
->community
, list
))
802 if (community_list_match (bgp_info
->attr
->community
, list
))
809 /* Compile function for community match. */
811 route_match_community_compile (const char *arg
)
813 struct rmap_community
*rcom
;
817 rcom
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_community
));
819 p
= strchr (arg
, ' ');
823 rcom
->name
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
824 memcpy (rcom
->name
, arg
, len
);
829 rcom
->name
= XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
835 /* Compile function for community match. */
837 route_match_community_free (void *rule
)
839 struct rmap_community
*rcom
= rule
;
841 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
->name
);
842 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcom
);
845 /* Route map commands for community matching. */
846 struct route_map_rule_cmd route_match_community_cmd
=
849 route_match_community
,
850 route_match_community_compile
,
851 route_match_community_free
854 /* Match function for extcommunity match. */
855 static route_map_result_t
856 route_match_ecommunity (void *rule
, struct prefix
*prefix
,
857 route_map_object_t type
, void *object
)
859 struct community_list
*list
;
860 struct bgp_info
*bgp_info
;
862 if (type
== RMAP_BGP
)
866 if (!bgp_info
->attr
->extra
)
869 list
= community_list_lookup (bgp_clist
, (char *) rule
,
870 EXTCOMMUNITY_LIST_MASTER
);
874 if (ecommunity_list_match (bgp_info
->attr
->extra
->ecommunity
, list
))
880 /* Compile function for extcommunity match. */
882 route_match_ecommunity_compile (const char *arg
)
884 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
887 /* Compile function for extcommunity match. */
889 route_match_ecommunity_free (void *rule
)
891 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
894 /* Route map commands for community matching. */
895 struct route_map_rule_cmd route_match_ecommunity_cmd
=
898 route_match_ecommunity
,
899 route_match_ecommunity_compile
,
900 route_match_ecommunity_free
903 /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
904 and `address-family vpnv4'. */
907 static route_map_result_t
908 route_match_origin (void *rule
, struct prefix
*prefix
,
909 route_map_object_t type
, void *object
)
912 struct bgp_info
*bgp_info
;
914 if (type
== RMAP_BGP
)
919 if (bgp_info
->attr
->origin
== *origin
)
927 route_match_origin_compile (const char *arg
)
931 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
933 if (strcmp (arg
, "igp") == 0)
935 else if (strcmp (arg
, "egp") == 0)
943 /* Free route map's compiled `ip address' value. */
945 route_match_origin_free (void *rule
)
947 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
950 /* Route map commands for origin matching. */
951 struct route_map_rule_cmd route_match_origin_cmd
=
955 route_match_origin_compile
,
956 route_match_origin_free
959 /* match probability { */
961 static route_map_result_t
962 route_match_probability (void *rule
, struct prefix
*prefix
,
963 route_map_object_t type
, void *object
)
967 switch (*(long *) rule
)
970 case RAND_MAX
: return RMAP_MATCH
;
972 if (r
< *(long *) rule
)
982 route_match_probability_compile (const char *arg
)
988 lobule
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (long));
992 case 0: *lobule
= 0; break;
993 case 100: *lobule
= RAND_MAX
; break;
994 default: *lobule
= RAND_MAX
/ 100 * perc
;
1001 route_match_probability_free (void *rule
)
1003 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1006 struct route_map_rule_cmd route_match_probability_cmd
=
1009 route_match_probability
,
1010 route_match_probability_compile
,
1011 route_match_probability_free
1014 /* `match interface IFNAME' */
1015 /* Match function should return 1 if match is success else return
1017 static route_map_result_t
1018 route_match_interface (void *rule
, struct prefix
*prefix
,
1019 route_map_object_t type
, void *object
)
1021 struct interface
*ifp
;
1022 struct bgp_info
*info
;
1024 if (type
== RMAP_BGP
)
1028 if (!info
|| !info
->attr
)
1029 return RMAP_NOMATCH
;
1031 ifp
= if_lookup_by_name_all_vrf ((char *)rule
);
1033 if (ifp
== NULL
|| ifp
->ifindex
!= info
->attr
->nh_ifindex
)
1034 return RMAP_NOMATCH
;
1038 return RMAP_NOMATCH
;
1041 /* Route map `interface' match statement. `arg' should be
1044 route_match_interface_compile (const char *arg
)
1046 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1049 /* Free route map's compiled `interface' value. */
1051 route_match_interface_free (void *rule
)
1053 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1056 /* Route map commands for ip address matching. */
1057 struct route_map_rule_cmd route_match_interface_cmd
=
1060 route_match_interface
,
1061 route_match_interface_compile
,
1062 route_match_interface_free
1067 /* `set ip next-hop IP_ADDRESS' */
1069 /* Match function return 1 if match is success else return zero. */
1070 static route_map_result_t
1071 route_match_tag (void *rule
, struct prefix
*prefix
,
1072 route_map_object_t type
, void *object
)
1075 struct bgp_info
*bgp_info
;
1077 if (type
== RMAP_BGP
)
1082 if (!bgp_info
->attr
->extra
)
1083 return RMAP_NOMATCH
;
1085 return ((bgp_info
->attr
->extra
->tag
== *tag
)? RMAP_MATCH
: RMAP_NOMATCH
);
1088 return RMAP_NOMATCH
;
1092 /* Route map commands for tag matching. */
1093 static struct route_map_rule_cmd route_match_tag_cmd
=
1097 route_map_rule_tag_compile
,
1098 route_map_rule_tag_free
,
1102 /* Set nexthop to object. ojbect must be pointer to struct attr. */
1103 struct rmap_ip_nexthop_set
1105 struct in_addr
*address
;
1110 static route_map_result_t
1111 route_set_ip_nexthop (void *rule
, struct prefix
*prefix
,
1112 route_map_object_t type
, void *object
)
1114 struct rmap_ip_nexthop_set
*rins
= rule
;
1115 struct bgp_info
*bgp_info
;
1118 if (type
== RMAP_BGP
)
1121 peer
= bgp_info
->peer
;
1123 if (rins
->unchanged
)
1125 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1126 BATTR_RMAP_NEXTHOP_UNCHANGED
);
1128 else if (rins
->peer_address
)
1130 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
1131 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
1133 && sockunion_family (peer
->su_remote
) == AF_INET
)
1135 bgp_info
->attr
->nexthop
.s_addr
= sockunion2ip (peer
->su_remote
);
1136 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1138 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
1140 /* The next hop value will be set as part of packet rewrite.
1141 * Set the flags here to indicate that rewrite needs to be done.
1142 * Also, clear the value.
1144 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1145 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
1146 bgp_info
->attr
->nexthop
.s_addr
= 0;
1151 /* Set next hop value. */
1152 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP
);
1153 bgp_info
->attr
->nexthop
= *rins
->address
;
1154 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
1155 BATTR_RMAP_IPV4_NHOP_CHANGED
);
1162 /* Route map `ip nexthop' compile function. Given string is converted
1163 to struct in_addr structure. */
1165 route_set_ip_nexthop_compile (const char *arg
)
1167 struct rmap_ip_nexthop_set
*rins
;
1168 struct in_addr
*address
= NULL
;
1169 int peer_address
= 0;
1173 if (strcmp (arg
, "peer-address") == 0)
1175 else if (strcmp (arg
, "unchanged") == 0)
1179 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
1180 ret
= inet_aton (arg
, address
);
1184 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
1189 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_ip_nexthop_set
));
1191 rins
->address
= address
;
1192 rins
->peer_address
= peer_address
;
1193 rins
->unchanged
= unchanged
;
1198 /* Free route map's compiled `ip nexthop' value. */
1200 route_set_ip_nexthop_free (void *rule
)
1202 struct rmap_ip_nexthop_set
*rins
= rule
;
1205 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
->address
);
1207 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rins
);
1210 /* Route map commands for ip nexthop set. */
1211 struct route_map_rule_cmd route_set_ip_nexthop_cmd
=
1214 route_set_ip_nexthop
,
1215 route_set_ip_nexthop_compile
,
1216 route_set_ip_nexthop_free
1219 /* `set local-preference LOCAL_PREF' */
1221 /* Set local preference. */
1222 static route_map_result_t
1223 route_set_local_pref (void *rule
, struct prefix
*prefix
,
1224 route_map_object_t type
, void *object
)
1226 struct rmap_value
*rv
;
1227 struct bgp_info
*bgp_info
;
1228 u_int32_t locpref
= 0;
1230 if (type
== RMAP_BGP
)
1232 /* Fetch routemap's rule information. */
1236 /* Set local preference value. */
1237 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
))
1238 locpref
= bgp_info
->attr
->local_pref
;
1240 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF
);
1241 bgp_info
->attr
->local_pref
= route_value_adjust(rv
, locpref
, bgp_info
->peer
);
1247 /* Set local preference rule structure. */
1248 struct route_map_rule_cmd route_set_local_pref_cmd
=
1251 route_set_local_pref
,
1252 route_value_compile
,
1256 /* `set weight WEIGHT' */
1259 static route_map_result_t
1260 route_set_weight (void *rule
, struct prefix
*prefix
, route_map_object_t type
,
1263 struct rmap_value
*rv
;
1264 struct bgp_info
*bgp_info
;
1267 if (type
== RMAP_BGP
)
1269 /* Fetch routemap's rule information. */
1273 /* Set weight value. */
1274 weight
= route_value_adjust(rv
, 0, bgp_info
->peer
);
1276 (bgp_attr_extra_get (bgp_info
->attr
))->weight
= weight
;
1277 else if (bgp_info
->attr
->extra
)
1278 bgp_info
->attr
->extra
->weight
= 0;
1284 /* Set local preference rule structure. */
1285 struct route_map_rule_cmd route_set_weight_cmd
=
1289 route_value_compile
,
1293 /* `set metric METRIC' */
1295 /* Set metric to attribute. */
1296 static route_map_result_t
1297 route_set_metric (void *rule
, struct prefix
*prefix
,
1298 route_map_object_t type
, void *object
)
1300 struct rmap_value
*rv
;
1301 struct bgp_info
*bgp_info
;
1304 if (type
== RMAP_BGP
)
1306 /* Fetch routemap's rule information. */
1310 if (bgp_info
->attr
->flag
& ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
))
1311 med
= bgp_info
->attr
->med
;
1313 bgp_info
->attr
->med
= route_value_adjust(rv
, med
, bgp_info
->peer
);
1314 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC
);
1319 /* Set metric rule structure. */
1320 struct route_map_rule_cmd route_set_metric_cmd
=
1324 route_value_compile
,
1328 /* `set as-path prepend ASPATH' */
1330 /* For AS path prepend mechanism. */
1331 static route_map_result_t
1332 route_set_aspath_prepend (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1334 struct aspath
*aspath
;
1336 struct bgp_info
*binfo
;
1338 if (type
== RMAP_BGP
)
1342 if (binfo
->attr
->aspath
->refcnt
)
1343 new = aspath_dup (binfo
->attr
->aspath
);
1345 new = binfo
->attr
->aspath
;
1347 if ((uintptr_t)rule
> 10)
1350 aspath_prepend (aspath
, new);
1354 as_t as
= aspath_leftmost(new);
1355 if (!as
) as
= binfo
->peer
->as
;
1356 new = aspath_add_seq_n (new, as
, (uintptr_t) rule
);
1359 binfo
->attr
->aspath
= new;
1366 route_set_aspath_prepend_compile (const char *arg
)
1370 if (sscanf(arg
, "last-as %u", &num
) == 1 && num
> 0 && num
< 10)
1371 return (void*)(uintptr_t)num
;
1373 return route_aspath_compile(arg
);
1377 route_set_aspath_prepend_free (void *rule
)
1379 if ((uintptr_t)rule
> 10)
1380 route_aspath_free(rule
);
1384 /* Set as-path prepend rule structure. */
1385 struct route_map_rule_cmd route_set_aspath_prepend_cmd
=
1388 route_set_aspath_prepend
,
1389 route_set_aspath_prepend_compile
,
1390 route_set_aspath_prepend_free
,
1393 /* `set as-path exclude ASn' */
1395 /* For ASN exclude mechanism.
1396 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1397 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1399 static route_map_result_t
1400 route_set_aspath_exclude (void *rule
, struct prefix
*dummy
, route_map_object_t type
, void *object
)
1402 struct aspath
* new_path
, * exclude_path
;
1403 struct bgp_info
*binfo
;
1405 if (type
== RMAP_BGP
)
1407 exclude_path
= rule
;
1409 if (binfo
->attr
->aspath
->refcnt
)
1410 new_path
= aspath_dup (binfo
->attr
->aspath
);
1412 new_path
= binfo
->attr
->aspath
;
1413 binfo
->attr
->aspath
= aspath_filter_exclude (new_path
, exclude_path
);
1418 /* Set ASn exlude rule structure. */
1419 struct route_map_rule_cmd route_set_aspath_exclude_cmd
=
1422 route_set_aspath_exclude
,
1423 route_aspath_compile
,
1427 /* `set community COMMUNITY' */
1430 struct community
*com
;
1435 /* For community set mechanism. */
1436 static route_map_result_t
1437 route_set_community (void *rule
, struct prefix
*prefix
,
1438 route_map_object_t type
, void *object
)
1440 struct rmap_com_set
*rcs
;
1441 struct bgp_info
*binfo
;
1443 struct community
*new = NULL
;
1444 struct community
*old
;
1445 struct community
*merge
;
1447 if (type
== RMAP_BGP
)
1452 old
= attr
->community
;
1457 attr
->flag
&= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
));
1458 attr
->community
= NULL
;
1459 /* See the longer comment down below. */
1460 if (old
&& old
->refcnt
== 0)
1461 community_free(old
);
1465 /* "additive" case. */
1466 if (rcs
->additive
&& old
)
1468 merge
= community_merge (community_dup (old
), rcs
->com
);
1470 /* HACK: if the old community is not intern'd,
1471 * we should free it here, or all reference to it may be lost.
1472 * Really need to cleanup attribute caching sometime.
1474 if (old
->refcnt
== 0)
1475 community_free (old
);
1476 new = community_uniq_sort (merge
);
1477 community_free (merge
);
1480 new = community_dup (rcs
->com
);
1482 /* will be interned by caller if required */
1483 attr
->community
= new;
1485 attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1491 /* Compile function for set community. */
1493 route_set_community_compile (const char *arg
)
1495 struct rmap_com_set
*rcs
;
1496 struct community
*com
= NULL
;
1501 if (strcmp (arg
, "none") == 0)
1505 sp
= strstr (arg
, "additive");
1509 /* "additive" keyworkd is included. */
1514 com
= community_str2com (arg
);
1523 rcs
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct rmap_com_set
));
1525 rcs
->additive
= additive
;
1531 /* Free function for set community. */
1533 route_set_community_free (void *rule
)
1535 struct rmap_com_set
*rcs
= rule
;
1538 community_free (rcs
->com
);
1539 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rcs
);
1542 /* Set community rule structure. */
1543 struct route_map_rule_cmd route_set_community_cmd
=
1546 route_set_community
,
1547 route_set_community_compile
,
1548 route_set_community_free
,
1551 /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
1553 /* For community set mechanism. */
1554 static route_map_result_t
1555 route_set_community_delete (void *rule
, struct prefix
*prefix
,
1556 route_map_object_t type
, void *object
)
1558 struct community_list
*list
;
1559 struct community
*merge
;
1560 struct community
*new;
1561 struct community
*old
;
1562 struct bgp_info
*binfo
;
1564 if (type
== RMAP_BGP
)
1570 list
= community_list_lookup (bgp_clist
, rule
, COMMUNITY_LIST_MASTER
);
1571 old
= binfo
->attr
->community
;
1575 merge
= community_list_match_delete (community_dup (old
), list
);
1576 new = community_uniq_sort (merge
);
1577 community_free (merge
);
1579 /* HACK: if the old community is not intern'd,
1580 * we should free it here, or all reference to it may be lost.
1581 * Really need to cleanup attribute caching sometime.
1583 if (old
->refcnt
== 0)
1584 community_free (old
);
1588 binfo
->attr
->community
= NULL
;
1589 binfo
->attr
->flag
&= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1590 community_free (new);
1594 binfo
->attr
->community
= new;
1595 binfo
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES
);
1603 /* Compile function for set community. */
1605 route_set_community_delete_compile (const char *arg
)
1611 p
= strchr (arg
, ' ');
1615 str
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, len
+ 1);
1616 memcpy (str
, arg
, len
);
1624 /* Free function for set community. */
1626 route_set_community_delete_free (void *rule
)
1628 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1631 /* Set community rule structure. */
1632 struct route_map_rule_cmd route_set_community_delete_cmd
=
1635 route_set_community_delete
,
1636 route_set_community_delete_compile
,
1637 route_set_community_delete_free
,
1640 /* `set extcommunity rt COMMUNITY' */
1642 /* For community set mechanism. Used by _rt and _soo. */
1643 static route_map_result_t
1644 route_set_ecommunity (void *rule
, struct prefix
*prefix
,
1645 route_map_object_t type
, void *object
)
1647 struct ecommunity
*ecom
;
1648 struct ecommunity
*new_ecom
;
1649 struct ecommunity
*old_ecom
;
1650 struct bgp_info
*bgp_info
;
1652 if (type
== RMAP_BGP
)
1660 /* We assume additive for Extended Community. */
1661 old_ecom
= (bgp_attr_extra_get (bgp_info
->attr
))->ecommunity
;
1665 new_ecom
= ecommunity_merge (ecommunity_dup (old_ecom
), ecom
);
1667 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1668 * ->refcnt = 0 => set by a previous route-map statement */
1669 if (!old_ecom
->refcnt
)
1670 ecommunity_free (&old_ecom
);
1673 new_ecom
= ecommunity_dup (ecom
);
1675 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1676 bgp_info
->attr
->extra
->ecommunity
= new_ecom
;
1678 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES
);
1683 /* Compile function for set community. */
1685 route_set_ecommunity_rt_compile (const char *arg
)
1687 struct ecommunity
*ecom
;
1689 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
1692 return ecommunity_intern (ecom
);
1695 /* Free function for set community. Used by _rt and _soo */
1697 route_set_ecommunity_free (void *rule
)
1699 struct ecommunity
*ecom
= rule
;
1700 ecommunity_unintern (&ecom
);
1703 /* Set community rule structure. */
1704 struct route_map_rule_cmd route_set_ecommunity_rt_cmd
=
1707 route_set_ecommunity
,
1708 route_set_ecommunity_rt_compile
,
1709 route_set_ecommunity_free
,
1712 /* `set extcommunity soo COMMUNITY' */
1714 /* Compile function for set community. */
1716 route_set_ecommunity_soo_compile (const char *arg
)
1718 struct ecommunity
*ecom
;
1720 ecom
= ecommunity_str2com (arg
, ECOMMUNITY_SITE_ORIGIN
, 0);
1724 return ecommunity_intern (ecom
);
1727 /* Set community rule structure. */
1728 struct route_map_rule_cmd route_set_ecommunity_soo_cmd
=
1731 route_set_ecommunity
,
1732 route_set_ecommunity_soo_compile
,
1733 route_set_ecommunity_free
,
1736 /* `set origin ORIGIN' */
1738 /* For origin set. */
1739 static route_map_result_t
1740 route_set_origin (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
1743 struct bgp_info
*bgp_info
;
1745 if (type
== RMAP_BGP
)
1750 bgp_info
->attr
->origin
= *origin
;
1756 /* Compile function for origin set. */
1758 route_set_origin_compile (const char *arg
)
1762 origin
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_char
));
1764 if (strcmp (arg
, "igp") == 0)
1766 else if (strcmp (arg
, "egp") == 0)
1774 /* Compile function for origin set. */
1776 route_set_origin_free (void *rule
)
1778 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1781 /* Set origin rule structure. */
1782 struct route_map_rule_cmd route_set_origin_cmd
=
1786 route_set_origin_compile
,
1787 route_set_origin_free
,
1790 /* `set atomic-aggregate' */
1792 /* For atomic aggregate set. */
1793 static route_map_result_t
1794 route_set_atomic_aggregate (void *rule
, struct prefix
*prefix
,
1795 route_map_object_t type
, void *object
)
1797 struct bgp_info
*bgp_info
;
1799 if (type
== RMAP_BGP
)
1802 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE
);
1808 /* Compile function for atomic aggregate. */
1810 route_set_atomic_aggregate_compile (const char *arg
)
1815 /* Compile function for atomic aggregate. */
1817 route_set_atomic_aggregate_free (void *rule
)
1822 /* Set atomic aggregate rule structure. */
1823 struct route_map_rule_cmd route_set_atomic_aggregate_cmd
=
1826 route_set_atomic_aggregate
,
1827 route_set_atomic_aggregate_compile
,
1828 route_set_atomic_aggregate_free
,
1831 /* `set aggregator as AS A.B.C.D' */
1835 struct in_addr address
;
1838 static route_map_result_t
1839 route_set_aggregator_as (void *rule
, struct prefix
*prefix
,
1840 route_map_object_t type
, void *object
)
1842 struct bgp_info
*bgp_info
;
1843 struct aggregator
*aggregator
;
1844 struct attr_extra
*ae
;
1846 if (type
== RMAP_BGP
)
1850 ae
= bgp_attr_extra_get (bgp_info
->attr
);
1852 ae
->aggregator_as
= aggregator
->as
;
1853 ae
->aggregator_addr
= aggregator
->address
;
1854 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR
);
1861 route_set_aggregator_as_compile (const char *arg
)
1863 struct aggregator
*aggregator
;
1867 aggregator
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct aggregator
));
1868 sscanf (arg
, "%s %s", as
, address
);
1870 aggregator
->as
= strtoul (as
, NULL
, 10);
1871 inet_aton (address
, &aggregator
->address
);
1877 route_set_aggregator_as_free (void *rule
)
1879 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1882 struct route_map_rule_cmd route_set_aggregator_as_cmd
=
1885 route_set_aggregator_as
,
1886 route_set_aggregator_as_compile
,
1887 route_set_aggregator_as_free
,
1890 /* Set tag to object. object must be pointer to struct bgp_info */
1891 static route_map_result_t
1892 route_set_tag (void *rule
, struct prefix
*prefix
,
1893 route_map_object_t type
, void *object
)
1896 struct bgp_info
*bgp_info
;
1897 struct attr_extra
*ae
;
1899 if (type
== RMAP_BGP
)
1903 ae
= bgp_attr_extra_get (bgp_info
->attr
);
1913 /* Route map commands for tag set. */
1914 static struct route_map_rule_cmd route_set_tag_cmd
=
1918 route_map_rule_tag_compile
,
1919 route_map_rule_tag_free
,
1924 /* `match ipv6 address IP_ACCESS_LIST' */
1926 static route_map_result_t
1927 route_match_ipv6_address (void *rule
, struct prefix
*prefix
,
1928 route_map_object_t type
, void *object
)
1930 struct access_list
*alist
;
1932 if (type
== RMAP_BGP
)
1934 alist
= access_list_lookup (AFI_IP6
, (char *) rule
);
1936 return RMAP_NOMATCH
;
1938 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
1939 RMAP_NOMATCH
: RMAP_MATCH
);
1941 return RMAP_NOMATCH
;
1945 route_match_ipv6_address_compile (const char *arg
)
1947 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
1951 route_match_ipv6_address_free (void *rule
)
1953 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
1956 /* Route map commands for ip address matching. */
1957 struct route_map_rule_cmd route_match_ipv6_address_cmd
=
1960 route_match_ipv6_address
,
1961 route_match_ipv6_address_compile
,
1962 route_match_ipv6_address_free
1965 /* `match ipv6 next-hop IP_ADDRESS' */
1967 static route_map_result_t
1968 route_match_ipv6_next_hop (void *rule
, struct prefix
*prefix
,
1969 route_map_object_t type
, void *object
)
1971 struct in6_addr
*addr
= rule
;
1972 struct bgp_info
*bgp_info
;
1974 if (type
== RMAP_BGP
)
1978 if (!bgp_info
->attr
->extra
)
1979 return RMAP_NOMATCH
;
1981 if (IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_global
, addr
))
1984 if (bgp_info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
&&
1985 IPV6_ADDR_SAME (&bgp_info
->attr
->extra
->mp_nexthop_local
, rule
))
1988 return RMAP_NOMATCH
;
1991 return RMAP_NOMATCH
;
1995 route_match_ipv6_next_hop_compile (const char *arg
)
1997 struct in6_addr
*address
;
2000 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2002 ret
= inet_pton (AF_INET6
, arg
, address
);
2005 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2013 route_match_ipv6_next_hop_free (void *rule
)
2015 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2018 struct route_map_rule_cmd route_match_ipv6_next_hop_cmd
=
2021 route_match_ipv6_next_hop
,
2022 route_match_ipv6_next_hop_compile
,
2023 route_match_ipv6_next_hop_free
2026 /* `match ipv6 address prefix-list PREFIX_LIST' */
2028 static route_map_result_t
2029 route_match_ipv6_address_prefix_list (void *rule
, struct prefix
*prefix
,
2030 route_map_object_t type
, void *object
)
2032 struct prefix_list
*plist
;
2034 if (type
== RMAP_BGP
)
2036 plist
= prefix_list_lookup (AFI_IP6
, (char *) rule
);
2038 return RMAP_NOMATCH
;
2040 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
2041 RMAP_NOMATCH
: RMAP_MATCH
);
2043 return RMAP_NOMATCH
;
2047 route_match_ipv6_address_prefix_list_compile (const char *arg
)
2049 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
2053 route_match_ipv6_address_prefix_list_free (void *rule
)
2055 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2058 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd
=
2060 "ipv6 address prefix-list",
2061 route_match_ipv6_address_prefix_list
,
2062 route_match_ipv6_address_prefix_list_compile
,
2063 route_match_ipv6_address_prefix_list_free
2066 /* `set ipv6 nexthop global IP_ADDRESS' */
2068 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2069 static route_map_result_t
2070 route_set_ipv6_nexthop_global (void *rule
, struct prefix
*prefix
,
2071 route_map_object_t type
, void *object
)
2073 struct in6_addr
*address
;
2074 struct bgp_info
*bgp_info
;
2076 if (type
== RMAP_BGP
)
2078 /* Fetch routemap's rule information. */
2082 /* Set next hop value. */
2083 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= *address
;
2085 /* Set nexthop length. */
2086 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2087 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
2089 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2090 BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED
);
2096 /* Route map `ip next-hop' compile function. Given string is converted
2097 to struct in_addr structure. */
2099 route_set_ipv6_nexthop_global_compile (const char *arg
)
2102 struct in6_addr
*address
;
2104 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2106 ret
= inet_pton (AF_INET6
, arg
, address
);
2110 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2117 /* Free route map's compiled `ip next-hop' value. */
2119 route_set_ipv6_nexthop_global_free (void *rule
)
2121 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2124 /* Route map commands for ip nexthop set. */
2125 struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd
=
2127 "ipv6 next-hop global",
2128 route_set_ipv6_nexthop_global
,
2129 route_set_ipv6_nexthop_global_compile
,
2130 route_set_ipv6_nexthop_global_free
2133 /* Set next-hop preference value. */
2134 static route_map_result_t
2135 route_set_ipv6_nexthop_prefer_global (void *rule
, struct prefix
*prefix
,
2136 route_map_object_t type
, void *object
)
2138 struct bgp_info
*bgp_info
;
2141 if (type
== RMAP_BGP
)
2143 /* Fetch routemap's rule information. */
2145 peer
= bgp_info
->peer
;
2147 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2148 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2150 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2152 /* Set next hop preference to global */
2153 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= TRUE
;
2154 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2155 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2159 bgp_info
->attr
->extra
->mp_nexthop_prefer_global
= FALSE
;
2160 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2161 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED
);
2168 route_set_ipv6_nexthop_prefer_global_compile (const char *arg
)
2172 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2178 /* Free route map's compiled `ip next-hop' value. */
2180 route_set_ipv6_nexthop_prefer_global_free (void *rule
)
2182 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2185 /* Route map commands for ip nexthop set preferred. */
2186 struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd
=
2188 "ipv6 next-hop prefer-global",
2189 route_set_ipv6_nexthop_prefer_global
,
2190 route_set_ipv6_nexthop_prefer_global_compile
,
2191 route_set_ipv6_nexthop_prefer_global_free
2194 /* `set ipv6 nexthop local IP_ADDRESS' */
2196 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2197 static route_map_result_t
2198 route_set_ipv6_nexthop_local (void *rule
, struct prefix
*prefix
,
2199 route_map_object_t type
, void *object
)
2201 struct in6_addr
*address
;
2202 struct bgp_info
*bgp_info
;
2204 if (type
== RMAP_BGP
)
2206 /* Fetch routemap's rule information. */
2210 /* Set next hop value. */
2211 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= *address
;
2213 /* Set nexthop length. */
2214 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
2215 bgp_info
->attr
->extra
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
2217 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2218 BATTR_RMAP_IPV6_LL_NHOP_CHANGED
);
2224 /* Route map `ip nexthop' compile function. Given string is converted
2225 to struct in_addr structure. */
2227 route_set_ipv6_nexthop_local_compile (const char *arg
)
2230 struct in6_addr
*address
;
2232 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
2234 ret
= inet_pton (AF_INET6
, arg
, address
);
2238 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2245 /* Free route map's compiled `ip nexthop' value. */
2247 route_set_ipv6_nexthop_local_free (void *rule
)
2249 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2252 /* Route map commands for ip nexthop set. */
2253 struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
2255 "ipv6 next-hop local",
2256 route_set_ipv6_nexthop_local
,
2257 route_set_ipv6_nexthop_local_compile
,
2258 route_set_ipv6_nexthop_local_free
2261 /* `set ipv6 nexthop peer-address' */
2263 /* Set nexthop to object. ojbect must be pointer to struct attr. */
2264 static route_map_result_t
2265 route_set_ipv6_nexthop_peer (void *rule
, struct prefix
*prefix
,
2266 route_map_object_t type
, void *object
)
2268 struct in6_addr peer_address
;
2269 struct bgp_info
*bgp_info
;
2272 if (type
== RMAP_BGP
)
2274 /* Fetch routemap's rule information. */
2276 peer
= bgp_info
->peer
;
2278 if ((CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IN
) ||
2279 CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_IMPORT
))
2281 && sockunion_family (peer
->su_remote
) == AF_INET6
)
2283 peer_address
= peer
->su_remote
->sin6
.sin6_addr
;
2284 /* Set next hop value and length in attribute. */
2285 if (IN6_IS_ADDR_LINKLOCAL(&peer_address
))
2287 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
= peer_address
;
2288 if (bgp_info
->attr
->extra
->mp_nexthop_len
!= 32)
2289 bgp_info
->attr
->extra
->mp_nexthop_len
= 32;
2293 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
= peer_address
;
2294 if (bgp_info
->attr
->extra
->mp_nexthop_len
== 0)
2295 bgp_info
->attr
->extra
->mp_nexthop_len
= 16;
2299 else if (CHECK_FLAG (peer
->rmap_type
, PEER_RMAP_TYPE_OUT
))
2301 /* The next hop value will be set as part of packet rewrite.
2302 * Set the flags here to indicate that rewrite needs to be done.
2303 * Also, clear the value - we clear both global and link-local
2304 * nexthops, whether we send one or both is determined elsewhere.
2306 SET_FLAG(bgp_info
->attr
->rmap_change_flags
,
2307 BATTR_RMAP_NEXTHOP_PEER_ADDRESS
);
2308 /* clear next hop value. */
2309 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global
),
2310 0, sizeof (struct in6_addr
));
2311 memset (&((bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_local
),
2312 0, sizeof (struct in6_addr
));
2319 /* Route map `ip next-hop' compile function. Given string is converted
2320 to struct in_addr structure. */
2322 route_set_ipv6_nexthop_peer_compile (const char *arg
)
2326 rins
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (int));
2332 /* Free route map's compiled `ip next-hop' value. */
2334 route_set_ipv6_nexthop_peer_free (void *rule
)
2336 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2339 /* Route map commands for ip nexthop set. */
2340 struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd
=
2342 "ipv6 next-hop peer-address",
2343 route_set_ipv6_nexthop_peer
,
2344 route_set_ipv6_nexthop_peer_compile
,
2345 route_set_ipv6_nexthop_peer_free
2348 #endif /* HAVE_IPV6 */
2350 /* `set vpnv4 nexthop A.B.C.D' */
2352 static route_map_result_t
2353 route_set_vpnv4_nexthop (void *rule
, struct prefix
*prefix
,
2354 route_map_object_t type
, void *object
)
2356 struct in_addr
*address
;
2357 struct bgp_info
*bgp_info
;
2359 if (type
== RMAP_BGP
)
2361 /* Fetch routemap's rule information. */
2365 /* Set next hop value. */
2366 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_global_in
= *address
;
2367 (bgp_attr_extra_get (bgp_info
->attr
))->mp_nexthop_len
= 4;
2374 route_set_vpnv4_nexthop_compile (const char *arg
)
2377 struct in_addr
*address
;
2379 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2381 ret
= inet_aton (arg
, address
);
2385 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2393 route_set_vpnv4_nexthop_free (void *rule
)
2395 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2398 /* Route map commands for ip nexthop set. */
2399 struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd
=
2402 route_set_vpnv4_nexthop
,
2403 route_set_vpnv4_nexthop_compile
,
2404 route_set_vpnv4_nexthop_free
2407 /* `set originator-id' */
2409 /* For origin set. */
2410 static route_map_result_t
2411 route_set_originator_id (void *rule
, struct prefix
*prefix
, route_map_object_t type
, void *object
)
2413 struct in_addr
*address
;
2414 struct bgp_info
*bgp_info
;
2416 if (type
== RMAP_BGP
)
2421 bgp_info
->attr
->flag
|= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID
);
2422 (bgp_attr_extra_get (bgp_info
->attr
))->originator_id
= *address
;
2428 /* Compile function for originator-id set. */
2430 route_set_originator_id_compile (const char *arg
)
2433 struct in_addr
*address
;
2435 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in_addr
));
2437 ret
= inet_aton (arg
, address
);
2441 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
2448 /* Compile function for originator_id set. */
2450 route_set_originator_id_free (void *rule
)
2452 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
2455 /* Set originator-id rule structure. */
2456 struct route_map_rule_cmd route_set_originator_id_cmd
=
2459 route_set_originator_id
,
2460 route_set_originator_id_compile
,
2461 route_set_originator_id_free
,
2464 /* Add bgp route map rule. */
2466 bgp_route_match_add (struct vty
*vty
, struct route_map_index
*index
,
2467 const char *command
, const char *arg
,
2468 route_map_event_t type
)
2472 ret
= route_map_add_match (index
, command
, arg
);
2477 case RMAP_RULE_MISSING
:
2478 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2480 case RMAP_COMPILE_ERROR
:
2481 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2486 if (type
!= RMAP_EVENT_MATCH_ADDED
)
2488 route_map_upd8_dependency (type
, arg
, index
->map
->name
);
2494 /* Delete bgp route map rule. */
2496 bgp_route_match_delete (struct vty
*vty
, struct route_map_index
*index
,
2497 const char *command
, const char *arg
,
2498 route_map_event_t type
)
2501 char *dep_name
= NULL
;
2503 char *rmap_name
= NULL
;
2505 if (type
!= RMAP_EVENT_MATCH_DELETED
)
2507 /* ignore the mundane, the types without any dependency */
2510 if ((tmpstr
= route_map_get_match_arg(index
, command
)) != NULL
)
2511 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, tmpstr
);
2515 dep_name
= XSTRDUP(MTYPE_ROUTE_MAP_RULE
, arg
);
2517 rmap_name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, index
->map
->name
);
2520 ret
= route_map_delete_match (index
, command
, dep_name
);
2525 case RMAP_RULE_MISSING
:
2526 vty_out (vty
, "%% BGP Can't find rule.%s", VTY_NEWLINE
);
2528 case RMAP_COMPILE_ERROR
:
2529 vty_out (vty
, "%% BGP Argument is malformed.%s", VTY_NEWLINE
);
2533 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2535 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2539 if (type
!= RMAP_EVENT_MATCH_DELETED
&& dep_name
)
2540 route_map_upd8_dependency(type
, dep_name
, rmap_name
);
2543 XFREE(MTYPE_ROUTE_MAP_RULE
, dep_name
);
2545 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
2551 * This is the workhorse routine for processing in/out routemap
2555 bgp_route_map_process_peer (const char *rmap_name
, struct route_map
*map
,
2556 struct peer
*peer
, int afi
, int safi
,
2561 struct bgp_filter
*filter
;
2563 if (!peer
|| !rmap_name
)
2566 filter
= &peer
->filter
[afi
][safi
];
2568 * in is for non-route-server clients,
2569 * out is for all peers
2571 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2573 if (filter
->map
[RMAP_IN
].name
&&
2574 (strcmp(rmap_name
, filter
->map
[RMAP_IN
].name
) == 0))
2576 filter
->map
[RMAP_IN
].map
= map
;
2578 if (route_update
&& peer
->status
== Established
)
2580 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2581 PEER_FLAG_SOFT_RECONFIG
))
2583 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2584 zlog_debug("Processing route_map %s update on "
2585 "peer %s (inbound, soft-reconfig)",
2586 rmap_name
, peer
->host
);
2588 bgp_soft_reconfig_in (peer
, afi
, safi
);
2590 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2591 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2594 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2595 zlog_debug("Processing route_map %s update on "
2596 "peer %s (inbound, route-refresh)",
2597 rmap_name
, peer
->host
);
2598 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2604 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_RSERVER_CLIENT
))
2608 if (update
&& route_update
&& peer
->status
== Established
)
2610 if (CHECK_FLAG (peer
->af_flags
[afi
][safi
],
2611 PEER_FLAG_SOFT_RECONFIG
))
2613 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2614 zlog_debug("Processing route_map %s update on "
2615 "peer %s (import, soft-reconfig)",
2616 rmap_name
, peer
->host
);
2618 bgp_soft_reconfig_in (peer
, afi
, safi
);
2620 else if (CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
2621 || CHECK_FLAG (peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
2623 if (bgp_debug_update(peer
, NULL
, NULL
, 1))
2624 zlog_debug("Processing route_map %s update on "
2625 "peer %s (import, route-refresh)",
2626 rmap_name
, peer
->host
);
2627 bgp_route_refresh_send (peer
, afi
, safi
, 0, 0, 0);
2629 /* DD: Else, what else do we do ? Reset peer ? */
2634 * For outbound, unsuppress and default-originate map change (content or
2635 * map created), merely update the "config" here, the actual route
2636 * announcement happens at the group level.
2638 if (filter
->map
[RMAP_OUT
].name
&&
2639 (strcmp(rmap_name
, filter
->map
[RMAP_OUT
].name
) == 0))
2640 filter
->map
[RMAP_OUT
].map
= map
;
2642 if (filter
->usmap
.name
&&
2643 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
2644 filter
->usmap
.map
= map
;
2646 if (peer
->default_rmap
[afi
][safi
].name
&&
2647 (strcmp (rmap_name
, peer
->default_rmap
[afi
][safi
].name
) == 0))
2648 peer
->default_rmap
[afi
][safi
].map
= map
;
2652 bgp_route_map_update_peer_group(const char *rmap_name
, struct route_map
*map
,
2655 struct peer_group
*group
;
2656 struct listnode
*node
, *nnode
;
2657 struct bgp_filter
*filter
;
2664 /* All the peers have been updated correctly already. This is
2665 * just updating the placeholder data. No real update required.
2667 for (ALL_LIST_ELEMENTS (bgp
->group
, node
, nnode
, group
))
2668 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2669 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2671 filter
= &group
->conf
->filter
[afi
][safi
];
2673 for (direct
= RMAP_IN
; direct
< RMAP_MAX
; direct
++)
2675 if ((filter
->map
[direct
].name
) &&
2676 (strcmp(rmap_name
, filter
->map
[direct
].name
) == 0))
2677 filter
->map
[direct
].map
= map
;
2680 if (filter
->usmap
.name
&&
2681 (strcmp(rmap_name
, filter
->usmap
.name
) == 0))
2682 filter
->usmap
.map
= map
;
2687 * Note that if an extreme number (tens of thousands) of route-maps are in use
2688 * and if bgp has an extreme number of peers, network statements, etc then this
2689 * function can consume a lot of cycles. This is due to this function being
2690 * called for each route-map and within this function we walk the list of peers,
2691 * network statements, etc looking to see if they use this route-map.
2694 bgp_route_map_process_update (struct bgp
*bgp
, const char *rmap_name
, int route_update
)
2700 struct bgp_node
*bn
;
2701 struct bgp_static
*bgp_static
;
2702 struct listnode
*node
, *nnode
;
2703 struct route_map
*map
;
2704 char buf
[INET6_ADDRSTRLEN
];
2706 map
= route_map_lookup_by_name (rmap_name
);
2708 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
2711 /* Ignore dummy peer-group structure */
2712 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2715 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2716 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2718 /* Ignore inactive AFI/SAFI */
2719 if (! peer
->afc
[afi
][safi
])
2722 /* process in/out/import/export/default-orig route-maps */
2723 bgp_route_map_process_peer(rmap_name
, map
, peer
, afi
, safi
, route_update
);
2727 /* for outbound/default-orig route-maps, process for groups */
2728 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
,
2731 /* update peer-group config (template) */
2732 bgp_route_map_update_peer_group(rmap_name
, map
, bgp
);
2734 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2735 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
2737 /* For table route-map updates. */
2738 if (bgp
->table_map
[afi
][safi
].name
&&
2739 (strcmp(rmap_name
, bgp
->table_map
[afi
][safi
].name
) == 0))
2741 bgp
->table_map
[afi
][safi
].map
= map
;
2743 if (BGP_DEBUG (zebra
, ZEBRA
))
2744 zlog_debug("Processing route_map %s update on "
2745 "table map", rmap_name
);
2747 bgp_zebra_announce_table(bgp
, afi
, safi
);
2750 /* For network route-map updates. */
2751 for (bn
= bgp_table_top (bgp
->route
[afi
][safi
]); bn
; bn
= bgp_route_next (bn
))
2752 if ((bgp_static
= bn
->info
) != NULL
)
2754 if (bgp_static
->rmap
.name
&&
2755 (strcmp(rmap_name
, bgp_static
->rmap
.name
) == 0))
2757 bgp_static
->rmap
.map
= map
;
2760 if (!bgp_static
->backdoor
)
2762 if (bgp_debug_zebra(&bn
->p
))
2763 zlog_debug("Processing route_map %s update on "
2764 "static route %s", rmap_name
,
2765 inet_ntop (bn
->p
.family
, &bn
->p
.u
.prefix
,
2766 buf
, INET6_ADDRSTRLEN
));
2767 bgp_static_update (bgp
, &bn
->p
, bgp_static
, afi
, safi
);
2773 /* For redistribute route-map updates. */
2774 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2775 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
2777 struct list
*red_list
;
2778 struct listnode
*node
;
2779 struct bgp_redist
*red
;
2781 red_list
= bgp
->redist
[afi
][i
];
2785 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
2787 if (red
->rmap
.name
&&
2788 (strcmp(rmap_name
, red
->rmap
.name
) == 0))
2790 red
->rmap
.map
= map
;
2794 if (BGP_DEBUG (zebra
, ZEBRA
))
2795 zlog_debug("Processing route_map %s update on "
2796 "redistributed routes", rmap_name
);
2798 bgp_redistribute_resend (bgp
, afi
, i
, red
->instance
);
2806 bgp_route_map_process_update_cb (char *rmap_name
)
2808 struct listnode
*node
, *nnode
;
2811 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2812 bgp_route_map_process_update(bgp
, rmap_name
, 1);
2815 zlog_debug("%s: calling vnc_routemap_update", __func__
);
2816 vnc_routemap_update(bgp
, __func__
);
2822 bgp_route_map_update_timer(struct thread
*thread
)
2824 bm
->t_rmap_update
= NULL
;
2826 route_map_walk_update_list(bgp_route_map_process_update_cb
);
2832 bgp_route_map_mark_update (const char *rmap_name
)
2834 if (bm
->t_rmap_update
== NULL
)
2836 struct listnode
*node
, *nnode
;
2839 /* rmap_update_timer of 0 means don't do route updates */
2840 if (bm
->rmap_update_timer
)
2843 thread_add_timer(bm
->master
, bgp_route_map_update_timer
, NULL
,
2844 bm
->rmap_update_timer
);
2846 /* Signal the groups that a route-map update event has started */
2847 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2848 update_group_policy_update(bgp
, BGP_POLICY_ROUTE_MAP
, rmap_name
, 1, 1);
2852 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
2853 bgp_route_map_process_update(bgp
, rmap_name
, 0);
2855 zlog_debug("%s: calling vnc_routemap_update", __func__
);
2856 vnc_routemap_update(bgp
, __func__
);
2863 bgp_route_map_add (const char *rmap_name
)
2865 if (route_map_mark_updated(rmap_name
, 0) == 0)
2866 bgp_route_map_mark_update(rmap_name
);
2868 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
2872 bgp_route_map_delete (const char *rmap_name
)
2874 if (route_map_mark_updated(rmap_name
, 1) == 0)
2875 bgp_route_map_mark_update(rmap_name
);
2877 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_DELETED
);
2881 bgp_route_map_event (route_map_event_t event
, const char *rmap_name
)
2883 if (route_map_mark_updated(rmap_name
, 0) == 0)
2884 bgp_route_map_mark_update(rmap_name
);
2886 route_map_notify_dependencies(rmap_name
, RMAP_EVENT_MATCH_ADDED
);
2892 "match peer <A.B.C.D|X:X::X:X>",
2894 "Match peer address\n"
2895 "IP address of peer\n"
2896 "IPv6 address of peer\n")
2899 return bgp_route_match_add (vty
, vty
->index
, "peer", argv
[idx_ip
]->arg
,
2900 RMAP_EVENT_MATCH_ADDED
);
2903 DEFUN (match_peer_local
,
2904 match_peer_local_cmd
,
2907 "Match peer address\n"
2908 "Static or Redistributed routes\n")
2910 return bgp_route_match_add (vty
, vty
->index
, "peer", "local",
2911 RMAP_EVENT_MATCH_DELETED
);
2914 DEFUN (no_match_peer
,
2916 "no match peer [<local|A.B.C.D|X:X::X:X>]",
2919 "Match peer address\n"
2920 "Static or Redistributed routes\n"
2921 "IP address of peer\n"
2922 "IPv6 address of peer\n")
2926 if (argc
<= idx_peer
)
2927 return bgp_route_match_delete (vty
, vty
->index
, "peer", NULL
,
2928 RMAP_EVENT_MATCH_DELETED
);
2929 return bgp_route_match_delete (vty
, vty
->index
, "peer", argv
[idx_peer
]->arg
,
2930 RMAP_EVENT_MATCH_DELETED
);
2934 /* match probability */
2935 DEFUN (match_probability
,
2936 match_probability_cmd
,
2937 "match probability (0-100)",
2939 "Match portion of routes defined by percentage value\n"
2940 "Percentage of routes\n")
2943 return bgp_route_match_add (vty
, vty
->index
, "probability", argv
[idx_number
]->arg
,
2944 RMAP_EVENT_MATCH_ADDED
);
2948 DEFUN (no_match_probability
,
2949 no_match_probability_cmd
,
2950 "no match probability [(1-99)]",
2953 "Match portion of routes defined by percentage value\n"
2954 "Percentage of routes\n")
2957 if (argc
<= idx_number
)
2958 return bgp_route_match_delete (vty
, vty
->index
, "probability", NULL
,
2959 RMAP_EVENT_MATCH_DELETED
);
2960 return bgp_route_match_delete (vty
, vty
->index
, "probability", argv
[idx_number
]->arg
,
2961 RMAP_EVENT_MATCH_DELETED
);
2965 DEFUN (match_ip_route_source
,
2966 match_ip_route_source_cmd
,
2967 "match ip route-source <(1-199)|(1300-2699)|WORD>",
2970 "Match advertising source address of route\n"
2971 "IP access-list number\n"
2972 "IP access-list number (expanded range)\n"
2973 "IP standard access-list name\n")
2976 return bgp_route_match_add (vty
, vty
->index
, "ip route-source", argv
[idx_acl
]->arg
,
2977 RMAP_EVENT_FILTER_ADDED
);
2981 DEFUN (no_match_ip_route_source
,
2982 no_match_ip_route_source_cmd
,
2983 "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
2987 "Match advertising source address of route\n"
2988 "IP access-list number\n"
2989 "IP access-list number (expanded range)\n"
2990 "IP standard access-list name\n")
2993 if (argc
<= idx_number
)
2994 return bgp_route_match_delete (vty
, vty
->index
, "ip route-source",
2995 NULL
, RMAP_EVENT_FILTER_DELETED
);
2996 return bgp_route_match_delete (vty
, vty
->index
, "ip route-source",
2997 argv
[idx_number
]->arg
, RMAP_EVENT_FILTER_DELETED
);
3001 DEFUN (match_ip_route_source_prefix_list
,
3002 match_ip_route_source_prefix_list_cmd
,
3003 "match ip route-source prefix-list WORD",
3006 "Match advertising source address of route\n"
3007 "Match entries of prefix-lists\n"
3008 "IP prefix-list name\n")
3011 return bgp_route_match_add (vty
, vty
->index
, "ip route-source prefix-list",
3012 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_ADDED
);
3016 DEFUN (no_match_ip_route_source_prefix_list
,
3017 no_match_ip_route_source_prefix_list_cmd
,
3018 "no match ip route-source prefix-list [WORD]",
3022 "Match advertising source address of route\n"
3023 "Match entries of prefix-lists\n"
3024 "IP prefix-list name\n")
3027 if (argc
<= idx_word
)
3028 return bgp_route_match_delete (vty
, vty
->index
, "ip route-source prefix-list",
3029 NULL
, RMAP_EVENT_PLIST_DELETED
);
3030 return bgp_route_match_delete (vty
, vty
->index
, "ip route-source prefix-list",
3031 argv
[idx_word
]->arg
, RMAP_EVENT_PLIST_DELETED
);
3035 DEFUN (match_local_pref
,
3036 match_local_pref_cmd
,
3037 "match local-preference (0-4294967295)",
3039 "Match local-preference of route\n"
3043 return bgp_route_match_add (vty
, vty
->index
, "local-preference", argv
[idx_number
]->arg
,
3044 RMAP_EVENT_MATCH_ADDED
);
3048 DEFUN (no_match_local_pref
,
3049 no_match_local_pref_cmd
,
3050 "no match local-preference [(0-4294967295)]",
3053 "Match local preference of route\n"
3054 "Local preference value\n")
3056 int idx_localpref
= 3;
3057 if (argc
<= idx_localpref
)
3058 return bgp_route_match_delete (vty
, vty
->index
, "local-preference",
3059 NULL
, RMAP_EVENT_MATCH_DELETED
);
3060 return bgp_route_match_delete (vty
, vty
->index
, "local-preference",
3061 argv
[idx_localpref
]->arg
,
3062 RMAP_EVENT_MATCH_DELETED
);
3066 DEFUN (match_community
,
3067 match_community_cmd
,
3068 "match community <(1-99)|(100-500)|WORD>",
3070 "Match BGP community list\n"
3071 "Community-list number (standard)\n"
3072 "Community-list number (expanded)\n"
3073 "Community-list name\n")
3075 int idx_comm_list
= 2;
3076 return bgp_route_match_add (vty
, vty
->index
, "community", argv
[idx_comm_list
]->arg
,
3077 RMAP_EVENT_CLIST_ADDED
);
3080 DEFUN (match_community_exact
,
3081 match_community_exact_cmd
,
3082 "match community <(1-99)|(100-500)|WORD> exact-match",
3084 "Match BGP community list\n"
3085 "Community-list number (standard)\n"
3086 "Community-list number (expanded)\n"
3087 "Community-list name\n"
3088 "Do exact matching of communities\n")
3090 int idx_comm_list
= 2;
3094 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3095 strlen (argv
[idx_comm_list
]->arg
) + strlen ("exact-match") + 2);
3097 sprintf (argstr
, "%s exact-match", argv
[idx_comm_list
]->arg
);
3099 ret
= bgp_route_match_add (vty
, vty
->index
, "community", argstr
,
3100 RMAP_EVENT_CLIST_ADDED
);
3102 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3107 DEFUN (no_match_community
,
3108 no_match_community_cmd
,
3109 "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
3112 "Match BGP community list\n"
3113 "Community-list number (standard)\n"
3114 "Community-list number (expanded)\n"
3115 "Community-list name\n"
3116 "Do exact matching of communities\n")
3118 return bgp_route_match_delete (vty
, vty
->index
, "community", NULL
,
3119 RMAP_EVENT_CLIST_DELETED
);
3124 DEFUN (match_ecommunity
,
3125 match_ecommunity_cmd
,
3126 "match extcommunity <(1-99)|(100-500)|WORD>",
3128 "Match BGP/VPN extended community list\n"
3129 "Extended community-list number (standard)\n"
3130 "Extended community-list number (expanded)\n"
3131 "Extended community-list name\n")
3133 int idx_comm_list
= 2;
3134 return bgp_route_match_add (vty
, vty
->index
, "extcommunity", argv
[idx_comm_list
]->arg
,
3135 RMAP_EVENT_ECLIST_ADDED
);
3139 DEFUN (no_match_ecommunity
,
3140 no_match_ecommunity_cmd
,
3141 "no match extcommunity [<(1-99)|(100-500)|WORD>]",
3144 "Match BGP/VPN extended community list\n"
3145 "Extended community-list number (standard)\n"
3146 "Extended community-list number (expanded)\n"
3147 "Extended community-list name\n")
3149 return bgp_route_match_delete (vty
, vty
->index
, "extcommunity", NULL
,
3150 RMAP_EVENT_ECLIST_DELETED
);
3154 DEFUN (match_aspath
,
3156 "match as-path WORD",
3158 "Match BGP AS path list\n"
3159 "AS path access-list name\n")
3162 return bgp_route_match_add (vty
, vty
->index
, "as-path", argv
[idx_word
]->arg
,
3163 RMAP_EVENT_ASLIST_ADDED
);
3167 DEFUN (no_match_aspath
,
3168 no_match_aspath_cmd
,
3169 "no match as-path [WORD]",
3172 "Match BGP AS path list\n"
3173 "AS path access-list name\n")
3175 return bgp_route_match_delete (vty
, vty
->index
, "as-path", NULL
,
3176 RMAP_EVENT_ASLIST_DELETED
);
3180 DEFUN (match_origin
,
3182 "match origin <egp|igp|incomplete>",
3187 "unknown heritage\n")
3190 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
3191 return bgp_route_match_add (vty
, vty
->index
, "origin", "igp",
3192 RMAP_EVENT_MATCH_ADDED
);
3193 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
3194 return bgp_route_match_add (vty
, vty
->index
, "origin", "egp",
3195 RMAP_EVENT_MATCH_ADDED
);
3196 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3197 return bgp_route_match_add (vty
, vty
->index
, "origin", "incomplete",
3198 RMAP_EVENT_MATCH_ADDED
);
3204 DEFUN (no_match_origin
,
3205 no_match_origin_cmd
,
3206 "no match origin [<egp|igp|incomplete>]",
3212 "unknown heritage\n")
3214 return bgp_route_match_delete (vty
, vty
->index
, "origin", NULL
,
3215 RMAP_EVENT_MATCH_DELETED
);
3218 DEFUN (set_ip_nexthop_peer
,
3219 set_ip_nexthop_peer_cmd
,
3220 "set ip next-hop peer-address",
3223 "Next hop address\n"
3224 "Use peer address (for BGP only)\n")
3226 return generic_set_add (vty
, vty
->index
, "ip next-hop", "peer-address");
3229 DEFUN (set_ip_nexthop_unchanged
,
3230 set_ip_nexthop_unchanged_cmd
,
3231 "set ip next-hop unchanged",
3234 "Next hop address\n"
3235 "Don't modify existing Next hop address\n")
3237 return generic_set_add (vty
, vty
->index
, "ip next-hop", "unchanged");
3241 DEFUN (set_local_pref
,
3243 "set local-preference (0-4294967295)",
3245 "BGP local preference path attribute\n"
3246 "Preference value\n")
3249 return generic_set_add (vty
, vty
->index
, "local-preference", argv
[idx_number
]->arg
);
3253 DEFUN (no_set_local_pref
,
3254 no_set_local_pref_cmd
,
3255 "no set local-preference [(0-4294967295)]",
3258 "BGP local preference path attribute\n"
3259 "Preference value\n")
3261 int idx_localpref
= 3;
3262 if (argc
<= idx_localpref
)
3263 return generic_set_delete (vty
, vty
->index
, "local-preference", NULL
);
3264 return generic_set_delete (vty
, vty
->index
, "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
->index
, "weight", argv
[idx_number
]->arg
);
3280 DEFUN (no_set_weight
,
3282 "no set weight [(0-4294967295)]",
3285 "BGP weight for routing table\n"
3289 if (argc
<= idx_weight
)
3290 return generic_set_delete (vty
, vty
->index
, "weight", NULL
);
3291 return generic_set_delete (vty
, vty
->index
, "weight", argv
[idx_weight
]->arg
);
3295 DEFUN (set_aspath_prepend_asn
,
3296 set_aspath_prepend_asn_cmd
,
3297 "set as-path prepend (1-4294967295)...",
3299 "Transform BGP AS_PATH attribute\n"
3300 "Prepend to the as-path\n"
3307 str
= argv_concat (argv
, argc
, idx_asn
);
3308 ret
= generic_set_add (vty
, vty
->index
, "as-path prepend", str
);
3309 XFREE (MTYPE_TMP
, str
);
3314 DEFUN (set_aspath_prepend_lastas
,
3315 set_aspath_prepend_lastas_cmd
,
3316 "set as-path prepend last-as (1-10)",
3318 "Transform BGP AS_PATH attribute\n"
3319 "Prepend to the as-path\n"
3320 "Use the peer's AS-number\n"
3321 "Number of times to insert")
3323 return set_aspath_prepend_asn (self
, vty
, argc
, argv
);
3326 DEFUN (no_set_aspath_prepend
,
3327 no_set_aspath_prepend_cmd
,
3328 "no set as-path prepend [(1-4294967295)]",
3331 "Transform BGP AS_PATH attribute\n"
3332 "Prepend to the as-path\n"
3339 str
= argv_concat (argv
, argc
, idx_asn
);
3340 ret
= generic_set_delete (vty
, vty
->index
, "as-path prepend", str
);
3341 XFREE (MTYPE_TMP
, str
);
3346 DEFUN (set_aspath_exclude
,
3347 set_aspath_exclude_cmd
,
3348 "set as-path exclude (1-4294967295)...",
3350 "Transform BGP AS-path attribute\n"
3351 "Exclude from the as-path\n"
3358 str
= argv_concat (argv
, argc
, idx_asn
);
3359 ret
= generic_set_add (vty
, vty
->index
, "as-path exclude", str
);
3360 XFREE (MTYPE_TMP
, str
);
3364 DEFUN (no_set_aspath_exclude
,
3365 no_set_aspath_exclude_cmd
,
3366 "no set as-path exclude (1-4294967295)...",
3369 "Transform BGP AS_PATH attribute\n"
3370 "Exclude from the as-path\n"
3377 str
= argv_concat (argv
, argc
, idx_asn
);
3378 ret
= generic_set_delete (vty
, vty
->index
, "as-path exclude", str
);
3379 XFREE (MTYPE_TMP
, str
);
3384 DEFUN (set_community
,
3386 "set community AA:NN...",
3388 "BGP community attribute\n"
3396 struct community
*com
= NULL
;
3401 b
= buffer_new (1024);
3403 for (i
= idx_aa_nn
; i
< argc
; i
++)
3405 if (strncmp (argv
[i
]->arg
, "additive", strlen (argv
[i
]->arg
)) == 0)
3412 buffer_putc (b
, ' ');
3416 if (strncmp (argv
[i
]->arg
, "internet", strlen (argv
[i
]->arg
)) == 0)
3418 buffer_putstr (b
, "internet");
3421 if (strncmp (argv
[i
]->arg
, "local-AS", strlen (argv
[i
]->arg
)) == 0)
3423 buffer_putstr (b
, "local-AS");
3426 if (strncmp (argv
[i
]->arg
, "no-a", strlen ("no-a")) == 0
3427 && strncmp (argv
[i
]->arg
, "no-advertise", strlen (argv
[i
]->arg
)) == 0)
3429 buffer_putstr (b
, "no-advertise");
3432 if (strncmp (argv
[i
]->arg
, "no-e", strlen ("no-e"))== 0
3433 && strncmp (argv
[i
]->arg
, "no-export", strlen (argv
[i
]->arg
)) == 0)
3435 buffer_putstr (b
, "no-export");
3438 buffer_putstr (b
, argv
[i
]->arg
);
3440 buffer_putc (b
, '\0');
3442 /* Fetch result string then compile it to communities attribute. */
3443 str
= buffer_getstr (b
);
3448 com
= community_str2com (str
);
3449 XFREE (MTYPE_TMP
, str
);
3452 /* Can't compile user input into communities attribute. */
3455 vty_out (vty
, "%% Malformed communities attribute%s", VTY_NEWLINE
);
3459 /* Set communites attribute string. */
3460 str
= community_str (com
);
3464 argstr
= XCALLOC (MTYPE_TMP
, strlen (str
) + strlen (" additive") + 1);
3465 strcpy (argstr
, str
);
3466 strcpy (argstr
+ strlen (str
), " additive");
3467 ret
= generic_set_add (vty
, vty
->index
, "community", argstr
);
3468 XFREE (MTYPE_TMP
, argstr
);
3471 ret
= generic_set_add (vty
, vty
->index
, "community", str
);
3473 community_free (com
);
3478 DEFUN (set_community_none
,
3479 set_community_none_cmd
,
3480 "set community none",
3482 "BGP community attribute\n"
3483 "No community attribute\n")
3485 return generic_set_add (vty
, vty
->index
, "community", "none");
3488 DEFUN (no_set_community
,
3489 no_set_community_cmd
,
3490 "no set community AA:NN...",
3493 "BGP community attribute\n"
3496 return generic_set_delete (vty
, vty
->index
, "community", NULL
);
3501 DEFUN (set_community_delete
,
3502 set_community_delete_cmd
,
3503 "set comm-list <(1-99)|(100-500)|WORD> delete",
3505 "set BGP community list (for deletion)\n"
3506 "Community-list number (standard)\n"
3507 "Community-list number (expanded)\n"
3508 "Community-list name\n"
3509 "Delete matching communities\n")
3511 int idx_comm_list
= 2;
3514 str
= XCALLOC (MTYPE_TMP
, strlen (argv
[idx_comm_list
]->arg
) + strlen (" delete") + 1);
3515 strcpy (str
, argv
[idx_comm_list
]->arg
);
3516 strcpy (str
+ strlen (argv
[idx_comm_list
]->arg
), " delete");
3518 generic_set_add (vty
, vty
->index
, "comm-list", str
);
3520 XFREE (MTYPE_TMP
, str
);
3524 DEFUN (no_set_community_delete
,
3525 no_set_community_delete_cmd
,
3526 "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
3529 "set BGP community list (for deletion)\n"
3530 "Community-list number (standard)\n"
3531 "Community-list number (expanded)\n"
3532 "Community-list name\n"
3533 "Delete matching communities\n")
3535 return generic_set_delete (vty
, vty
->index
, "comm-list", NULL
);
3539 DEFUN (set_ecommunity_rt
,
3540 set_ecommunity_rt_cmd
,
3541 "set extcommunity rt ASN:nn_or_IP-address:nn...",
3543 "BGP extended community attribute\n"
3544 "Route Target extended community\n"
3545 "VPN extended community\n")
3551 str
= argv_concat (argv
, argc
, idx_asn_nn
);
3552 ret
= generic_set_add (vty
, vty
->index
, "extcommunity rt", str
);
3553 XFREE (MTYPE_TMP
, str
);
3558 DEFUN (no_set_ecommunity_rt
,
3559 no_set_ecommunity_rt_cmd
,
3560 "no set extcommunity rt ASN:nn_or_IP-address:nn...",
3563 "BGP extended community attribute\n"
3564 "Route Target extended community\n")
3566 return generic_set_delete (vty
, vty
->index
, "extcommunity rt", NULL
);
3570 DEFUN (set_ecommunity_soo
,
3571 set_ecommunity_soo_cmd
,
3572 "set extcommunity soo ASN:nn_or_IP-address:nn...",
3574 "BGP extended community attribute\n"
3575 "Site-of-Origin extended community\n"
3576 "VPN extended community\n")
3582 str
= argv_concat (argv
, argc
, idx_asn_nn
);
3583 ret
= generic_set_add (vty
, vty
->index
, "extcommunity soo", str
);
3584 XFREE (MTYPE_TMP
, str
);
3589 DEFUN (no_set_ecommunity_soo
,
3590 no_set_ecommunity_soo_cmd
,
3591 "no set extcommunity soo ASN:nn_or_IP-address:nn...",
3594 "BGP extended community attribute\n"
3595 "Site-of-Origin extended community\n")
3597 return generic_set_delete (vty
, vty
->index
, "extcommunity soo", NULL
);
3603 "set origin <egp|igp|incomplete>",
3608 "unknown heritage\n")
3611 if (strncmp (argv
[idx_origin
]->arg
, "igp", 2) == 0)
3612 return generic_set_add (vty
, vty
->index
, "origin", "igp");
3613 if (strncmp (argv
[idx_origin
]->arg
, "egp", 1) == 0)
3614 return generic_set_add (vty
, vty
->index
, "origin", "egp");
3615 if (strncmp (argv
[idx_origin
]->arg
, "incomplete", 2) == 0)
3616 return generic_set_add (vty
, vty
->index
, "origin", "incomplete");
3622 DEFUN (no_set_origin
,
3624 "no set origin [<egp|igp|incomplete>]",
3630 "unknown heritage\n")
3632 return generic_set_delete (vty
, vty
->index
, "origin", NULL
);
3636 DEFUN (set_atomic_aggregate
,
3637 set_atomic_aggregate_cmd
,
3638 "set atomic-aggregate",
3640 "BGP atomic aggregate attribute\n" )
3642 return generic_set_add (vty
, vty
->index
, "atomic-aggregate", NULL
);
3645 DEFUN (no_set_atomic_aggregate
,
3646 no_set_atomic_aggregate_cmd
,
3647 "no set atomic-aggregate",
3650 "BGP atomic aggregate attribute\n" )
3652 return generic_set_delete (vty
, vty
->index
, "atomic-aggregate", NULL
);
3655 DEFUN (set_aggregator_as
,
3656 set_aggregator_as_cmd
,
3657 "set aggregator as (1-4294967295) A.B.C.D",
3659 "BGP aggregator attribute\n"
3660 "AS number of aggregator\n"
3662 "IP address of aggregator\n")
3667 struct in_addr address
;
3670 ret
= inet_aton (argv
[idx_ipv4
]->arg
, &address
);
3673 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
3677 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3678 strlen (argv
[idx_number
]->arg
) + strlen (argv
[idx_ipv4
]->arg
) + 2);
3680 sprintf (argstr
, "%s %s", argv
[idx_number
]->arg
, argv
[idx_ipv4
]->arg
);
3682 ret
= generic_set_add (vty
, vty
->index
, "aggregator as", argstr
);
3684 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3690 DEFUN (no_set_aggregator_as
,
3691 no_set_aggregator_as_cmd
,
3692 "no set aggregator as [(1-4294967295) A.B.C.D]",
3695 "BGP aggregator attribute\n"
3696 "AS number of aggregator\n"
3698 "IP address of aggregator\n")
3703 struct in_addr address
;
3706 if (argc
<= idx_asn
)
3707 return generic_set_delete (vty
, vty
->index
, "aggregator as", NULL
);
3709 ret
= inet_aton (argv
[idx_ip
]->arg
, &address
);
3712 vty_out (vty
, "Aggregator IP address is invalid%s", VTY_NEWLINE
);
3716 argstr
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
3717 strlen (argv
[idx_asn
]->arg
) + strlen (argv
[idx_ip
]->arg
) + 2);
3719 sprintf (argstr
, "%s %s", argv
[idx_asn
]->arg
, argv
[idx_ip
]->arg
);
3721 ret
= generic_set_delete (vty
, vty
->index
, "aggregator as", argstr
);
3723 XFREE (MTYPE_ROUTE_MAP_COMPILED
, argstr
);
3729 DEFUN (match_ipv6_next_hop
,
3730 match_ipv6_next_hop_cmd
,
3731 "match ipv6 next-hop X:X::X:X",
3734 "Match IPv6 next-hop address of route\n"
3735 "IPv6 address of next hop\n")
3738 return bgp_route_match_add (vty
, vty
->index
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
3739 RMAP_EVENT_MATCH_ADDED
);
3742 DEFUN (no_match_ipv6_next_hop
,
3743 no_match_ipv6_next_hop_cmd
,
3744 "no match ipv6 next-hop X:X::X:X",
3748 "Match IPv6 next-hop address of route\n"
3749 "IPv6 address of next hop\n")
3752 return bgp_route_match_delete (vty
, vty
->index
, "ipv6 next-hop", argv
[idx_ipv6
]->arg
,
3753 RMAP_EVENT_MATCH_DELETED
);
3757 DEFUN (set_ipv6_nexthop_peer
,
3758 set_ipv6_nexthop_peer_cmd
,
3759 "set ipv6 next-hop peer-address",
3762 "Next hop address\n"
3763 "Use peer address (for BGP only)\n")
3765 return generic_set_add (vty
, vty
->index
, "ipv6 next-hop peer-address", NULL
);
3768 DEFUN (no_set_ipv6_nexthop_peer
,
3769 no_set_ipv6_nexthop_peer_cmd
,
3770 "no set ipv6 next-hop peer-address",
3774 "IPv6 next-hop address\n"
3775 "Use peer address (for BGP only)\n")
3777 return generic_set_delete (vty
, vty
->index
, "ipv6 next-hop peer-address", NULL
);
3780 DEFUN (set_ipv6_nexthop_prefer_global
,
3781 set_ipv6_nexthop_prefer_global_cmd
,
3782 "set ipv6 next-hop prefer-global",
3785 "IPv6 next-hop address\n"
3786 "Prefer global over link-local if both exist\n")
3788 return generic_set_add (vty
, vty
->index
, "ipv6 next-hop prefer-global", NULL
);;
3791 DEFUN (no_set_ipv6_nexthop_prefer_global
,
3792 no_set_ipv6_nexthop_prefer_global_cmd
,
3793 "no set ipv6 next-hop prefer-global",
3797 "IPv6 next-hop address\n"
3798 "Prefer global over link-local if both exist\n")
3800 return generic_set_delete (vty
, vty
->index
, "ipv6 next-hop prefer-global", NULL
);
3803 DEFUN (set_ipv6_nexthop_global
,
3804 set_ipv6_nexthop_global_cmd
,
3805 "set ipv6 next-hop global X:X::X:X",
3808 "IPv6 next-hop address\n"
3809 "IPv6 global address\n"
3810 "IPv6 address of next hop\n")
3813 struct in6_addr addr
;
3816 ret
= inet_pton (AF_INET6
, argv
[idx_ipv6
]->arg
, &addr
);
3819 vty_out (vty
, "%% Malformed nexthop address%s", VTY_NEWLINE
);
3822 if (IN6_IS_ADDR_UNSPECIFIED(&addr
) ||
3823 IN6_IS_ADDR_LOOPBACK(&addr
) ||
3824 IN6_IS_ADDR_MULTICAST(&addr
) ||
3825 IN6_IS_ADDR_LINKLOCAL(&addr
))
3827 vty_out (vty
, "%% Invalid global nexthop address%s", VTY_NEWLINE
);
3831 return generic_set_add (vty
, vty
->index
, "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
3835 DEFUN (no_set_ipv6_nexthop_global
,
3836 no_set_ipv6_nexthop_global_cmd
,
3837 "no set ipv6 next-hop global X:X::X:X",
3841 "IPv6 next-hop address\n"
3842 "IPv6 global address\n"
3843 "IPv6 address of next hop\n")
3846 if (argc
<= idx_ipv6
)
3847 return generic_set_delete (vty
, vty
->index
, "ipv6 next-hop global", NULL
);
3848 return generic_set_delete (vty
, vty
->index
, "ipv6 next-hop global", argv
[idx_ipv6
]->arg
);
3850 #endif /* HAVE_IPV6 */
3852 DEFUN (set_vpnv4_nexthop
,
3853 set_vpnv4_nexthop_cmd
,
3854 "set vpnv4 next-hop A.B.C.D",
3856 "VPNv4 information\n"
3857 "VPNv4 next-hop address\n"
3858 "IP address of next hop\n")
3861 return generic_set_add (vty
, vty
->index
, "vpnv4 next-hop", argv
[idx_ipv4
]->arg
);
3865 DEFUN (no_set_vpnv4_nexthop
,
3866 no_set_vpnv4_nexthop_cmd
,
3867 "no set vpnv4 next-hop [A.B.C.D]",
3870 "VPNv4 information\n"
3871 "VPNv4 next-hop address\n"
3872 "IP address of next hop\n")
3875 if (argc
<= idx_ipv4
)
3876 return generic_set_delete (vty
, vty
->index
, "vpnv4 next-hop", NULL
);
3877 return generic_set_delete (vty
, vty
->index
, "vpnv4 next-hop", argv
[idx_ipv4
]->arg
);
3881 DEFUN (set_originator_id
,
3882 set_originator_id_cmd
,
3883 "set originator-id A.B.C.D",
3885 "BGP originator ID attribute\n"
3886 "IP address of originator\n")
3889 return generic_set_add (vty
, vty
->index
, "originator-id", argv
[idx_ipv4
]->arg
);
3893 DEFUN (no_set_originator_id
,
3894 no_set_originator_id_cmd
,
3895 "no set originator-id [A.B.C.D]",
3898 "BGP originator ID attribute\n"
3899 "IP address of originator\n")
3903 return generic_set_delete (vty
, vty
->index
, "originator-id", NULL
);
3904 return generic_set_delete (vty
, vty
->index
, "originator-id", argv
[idx_id
]->arg
);
3908 /* Initialization of route map. */
3910 bgp_route_map_init (void)
3914 route_map_add_hook (bgp_route_map_add
);
3915 route_map_delete_hook (bgp_route_map_delete
);
3916 route_map_event_hook (bgp_route_map_event
);
3918 route_map_match_interface_hook (generic_match_add
);
3919 route_map_no_match_interface_hook (generic_match_delete
);
3921 route_map_match_ip_address_hook (generic_match_add
);
3922 route_map_no_match_ip_address_hook (generic_match_delete
);
3924 route_map_match_ip_address_prefix_list_hook (generic_match_add
);
3925 route_map_no_match_ip_address_prefix_list_hook (generic_match_delete
);
3927 route_map_match_ip_next_hop_hook (generic_match_add
);
3928 route_map_no_match_ip_next_hop_hook (generic_match_delete
);
3930 route_map_match_ip_next_hop_prefix_list_hook (generic_match_add
);
3931 route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete
);
3933 route_map_match_ipv6_address_hook (generic_match_add
);
3934 route_map_no_match_ipv6_address_hook (generic_match_delete
);
3936 route_map_match_ipv6_address_prefix_list_hook (generic_match_add
);
3937 route_map_no_match_ipv6_address_prefix_list_hook (generic_match_delete
);
3939 route_map_match_metric_hook (generic_match_add
);
3940 route_map_no_match_metric_hook (generic_match_delete
);
3942 route_map_match_tag_hook (generic_match_add
);
3943 route_map_no_match_tag_hook (generic_match_delete
);
3945 route_map_set_ip_nexthop_hook (generic_set_add
);
3946 route_map_no_set_ip_nexthop_hook (generic_set_delete
);
3948 route_map_set_ipv6_nexthop_local_hook (generic_set_add
);
3949 route_map_no_set_ipv6_nexthop_local_hook (generic_set_delete
);
3951 route_map_set_metric_hook (generic_set_add
);
3952 route_map_no_set_metric_hook (generic_set_delete
);
3954 route_map_set_tag_hook (generic_set_add
);
3955 route_map_no_set_tag_hook (generic_set_delete
);
3957 route_map_install_match (&route_match_peer_cmd
);
3958 route_map_install_match (&route_match_local_pref_cmd
);
3959 route_map_install_match (&route_match_ip_address_cmd
);
3960 route_map_install_match (&route_match_ip_next_hop_cmd
);
3961 route_map_install_match (&route_match_ip_route_source_cmd
);
3962 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
3963 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
3964 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd
);
3965 route_map_install_match (&route_match_aspath_cmd
);
3966 route_map_install_match (&route_match_community_cmd
);
3967 route_map_install_match (&route_match_ecommunity_cmd
);
3968 route_map_install_match (&route_match_local_pref_cmd
);
3969 route_map_install_match (&route_match_metric_cmd
);
3970 route_map_install_match (&route_match_origin_cmd
);
3971 route_map_install_match (&route_match_probability_cmd
);
3972 route_map_install_match (&route_match_interface_cmd
);
3973 route_map_install_match (&route_match_tag_cmd
);
3975 route_map_install_set (&route_set_ip_nexthop_cmd
);
3976 route_map_install_set (&route_set_local_pref_cmd
);
3977 route_map_install_set (&route_set_weight_cmd
);
3978 route_map_install_set (&route_set_metric_cmd
);
3979 route_map_install_set (&route_set_aspath_prepend_cmd
);
3980 route_map_install_set (&route_set_aspath_exclude_cmd
);
3981 route_map_install_set (&route_set_origin_cmd
);
3982 route_map_install_set (&route_set_atomic_aggregate_cmd
);
3983 route_map_install_set (&route_set_aggregator_as_cmd
);
3984 route_map_install_set (&route_set_community_cmd
);
3985 route_map_install_set (&route_set_community_delete_cmd
);
3986 route_map_install_set (&route_set_vpnv4_nexthop_cmd
);
3987 route_map_install_set (&route_set_originator_id_cmd
);
3988 route_map_install_set (&route_set_ecommunity_rt_cmd
);
3989 route_map_install_set (&route_set_ecommunity_soo_cmd
);
3990 route_map_install_set (&route_set_tag_cmd
);
3992 install_element (RMAP_NODE
, &match_peer_cmd
);
3993 install_element (RMAP_NODE
, &match_peer_local_cmd
);
3994 install_element (RMAP_NODE
, &no_match_peer_cmd
);
3995 install_element (RMAP_NODE
, &match_ip_route_source_cmd
);
3996 install_element (RMAP_NODE
, &no_match_ip_route_source_cmd
);
3997 install_element (RMAP_NODE
, &match_ip_route_source_prefix_list_cmd
);
3998 install_element (RMAP_NODE
, &no_match_ip_route_source_prefix_list_cmd
);
4000 install_element (RMAP_NODE
, &match_aspath_cmd
);
4001 install_element (RMAP_NODE
, &no_match_aspath_cmd
);
4002 install_element (RMAP_NODE
, &match_local_pref_cmd
);
4003 install_element (RMAP_NODE
, &no_match_local_pref_cmd
);
4004 install_element (RMAP_NODE
, &match_community_cmd
);
4005 install_element (RMAP_NODE
, &match_community_exact_cmd
);
4006 install_element (RMAP_NODE
, &no_match_community_cmd
);
4007 install_element (RMAP_NODE
, &match_ecommunity_cmd
);
4008 install_element (RMAP_NODE
, &no_match_ecommunity_cmd
);
4009 install_element (RMAP_NODE
, &match_origin_cmd
);
4010 install_element (RMAP_NODE
, &no_match_origin_cmd
);
4011 install_element (RMAP_NODE
, &match_probability_cmd
);
4012 install_element (RMAP_NODE
, &no_match_probability_cmd
);
4014 install_element (RMAP_NODE
, &set_ip_nexthop_peer_cmd
);
4015 install_element (RMAP_NODE
, &set_ip_nexthop_unchanged_cmd
);
4016 install_element (RMAP_NODE
, &set_local_pref_cmd
);
4017 install_element (RMAP_NODE
, &no_set_local_pref_cmd
);
4018 install_element (RMAP_NODE
, &set_weight_cmd
);
4019 install_element (RMAP_NODE
, &no_set_weight_cmd
);
4020 install_element (RMAP_NODE
, &set_aspath_prepend_asn_cmd
);
4021 install_element (RMAP_NODE
, &set_aspath_prepend_lastas_cmd
);
4022 install_element (RMAP_NODE
, &set_aspath_exclude_cmd
);
4023 install_element (RMAP_NODE
, &no_set_aspath_prepend_cmd
);
4024 install_element (RMAP_NODE
, &no_set_aspath_exclude_cmd
);
4025 install_element (RMAP_NODE
, &set_origin_cmd
);
4026 install_element (RMAP_NODE
, &no_set_origin_cmd
);
4027 install_element (RMAP_NODE
, &set_atomic_aggregate_cmd
);
4028 install_element (RMAP_NODE
, &no_set_atomic_aggregate_cmd
);
4029 install_element (RMAP_NODE
, &set_aggregator_as_cmd
);
4030 install_element (RMAP_NODE
, &no_set_aggregator_as_cmd
);
4031 install_element (RMAP_NODE
, &set_community_cmd
);
4032 install_element (RMAP_NODE
, &set_community_none_cmd
);
4033 install_element (RMAP_NODE
, &no_set_community_cmd
);
4034 install_element (RMAP_NODE
, &set_community_delete_cmd
);
4035 install_element (RMAP_NODE
, &no_set_community_delete_cmd
);
4036 install_element (RMAP_NODE
, &set_ecommunity_rt_cmd
);
4037 install_element (RMAP_NODE
, &no_set_ecommunity_rt_cmd
);
4038 install_element (RMAP_NODE
, &set_ecommunity_soo_cmd
);
4039 install_element (RMAP_NODE
, &no_set_ecommunity_soo_cmd
);
4040 install_element (RMAP_NODE
, &set_vpnv4_nexthop_cmd
);
4041 install_element (RMAP_NODE
, &no_set_vpnv4_nexthop_cmd
);
4042 install_element (RMAP_NODE
, &set_originator_id_cmd
);
4043 install_element (RMAP_NODE
, &no_set_originator_id_cmd
);
4046 route_map_install_match (&route_match_ipv6_address_cmd
);
4047 route_map_install_match (&route_match_ipv6_next_hop_cmd
);
4048 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd
);
4049 route_map_install_set (&route_set_ipv6_nexthop_global_cmd
);
4050 route_map_install_set (&route_set_ipv6_nexthop_prefer_global_cmd
);
4051 route_map_install_set (&route_set_ipv6_nexthop_local_cmd
);
4052 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd
);
4054 install_element (RMAP_NODE
, &match_ipv6_next_hop_cmd
);
4055 install_element (RMAP_NODE
, &no_match_ipv6_next_hop_cmd
);
4056 install_element (RMAP_NODE
, &set_ipv6_nexthop_global_cmd
);
4057 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_global_cmd
);
4058 install_element (RMAP_NODE
, &set_ipv6_nexthop_prefer_global_cmd
);
4059 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_prefer_global_cmd
);
4060 install_element (RMAP_NODE
, &set_ipv6_nexthop_peer_cmd
);
4061 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_peer_cmd
);
4062 #endif /* HAVE_IPV6 */
4066 bgp_route_map_terminate (void)
4068 /* ToDo: Cleanup all the used memory */
4070 route_map_add_hook (NULL
);
4071 route_map_delete_hook (NULL
);
4072 route_map_event_hook (NULL
);