]>
Commit | Line | Data |
---|---|---|
eb5d44eb | 1 | /* |
f3ccedaa | 2 | * IS-IS Rout(e)ing protocol - isis_routemap.c |
eb5d44eb | 3 | * |
f3ccedaa | 4 | * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> |
eb5d44eb | 5 | * |
d62a17ae | 6 | * This program 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 Free | |
8 | * Software Foundation; either version 2 of the License, or (at your option) | |
eb5d44eb | 9 | * any later version. |
10 | * | |
d62a17ae | 11 | * This program is distributed in the hope that it will be useful,but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
eb5d44eb | 14 | * more details. |
896014f4 DL |
15 | * |
16 | * You should have received a copy of the GNU General Public License along | |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
eb5d44eb | 19 | */ |
f3ccedaa | 20 | |
eb5d44eb | 21 | #include <zebra.h> |
eb5d44eb | 22 | |
f3ccedaa CF |
23 | #include "command.h" |
24 | #include "filter.h" | |
25 | #include "hash.h" | |
26 | #include "if.h" | |
eb5d44eb | 27 | #include "linklist.h" |
eb5d44eb | 28 | #include "log.h" |
29 | #include "memory.h" | |
30 | #include "prefix.h" | |
f3ccedaa | 31 | #include "plist.h" |
eb5d44eb | 32 | #include "routemap.h" |
f3ccedaa CF |
33 | #include "table.h" |
34 | #include "thread.h" | |
35 | #include "vty.h" | |
eb5d44eb | 36 | |
37 | #include "isis_constants.h" | |
38 | #include "isis_common.h" | |
3f045a08 | 39 | #include "isis_flags.h" |
eb5d44eb | 40 | #include "dict.h" |
41 | #include "isisd.h" | |
42 | #include "isis_misc.h" | |
43 | #include "isis_adjacency.h" | |
44 | #include "isis_circuit.h" | |
eb5d44eb | 45 | #include "isis_pdu.h" |
46 | #include "isis_lsp.h" | |
47 | #include "isis_spf.h" | |
48 | #include "isis_route.h" | |
49 | #include "isis_zebra.h" | |
f3ccedaa | 50 | #include "isis_routemap.h" |
eb5d44eb | 51 | |
d62a17ae | 52 | static route_map_result_t route_match_ip_address(void *rule, |
123214ef | 53 | const struct prefix *prefix, |
d62a17ae | 54 | route_map_object_t type, |
55 | void *object) | |
f3ccedaa | 56 | { |
d62a17ae | 57 | struct access_list *alist; |
eb5d44eb | 58 | |
d62a17ae | 59 | if (type != RMAP_ISIS) |
60 | return RMAP_NOMATCH; | |
41b36e90 | 61 | |
d62a17ae | 62 | alist = access_list_lookup(AFI_IP, (char *)rule); |
63 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
64 | return RMAP_MATCH; | |
41b36e90 | 65 | |
d62a17ae | 66 | return RMAP_NOMATCH; |
f3ccedaa CF |
67 | } |
68 | ||
d62a17ae | 69 | static void *route_match_ip_address_compile(const char *arg) |
f3ccedaa | 70 | { |
d62a17ae | 71 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
72 | } |
73 | ||
d62a17ae | 74 | static void route_match_ip_address_free(void *rule) |
f3ccedaa | 75 | { |
d62a17ae | 76 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
77 | } |
78 | ||
d62a17ae | 79 | static struct route_map_rule_cmd route_match_ip_address_cmd = { |
80 | "ip address", route_match_ip_address, route_match_ip_address_compile, | |
81 | route_match_ip_address_free}; | |
f3ccedaa CF |
82 | |
83 | /* ------------------------------------------------------------*/ | |
84 | ||
85 | static route_map_result_t | |
123214ef | 86 | route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix, |
d62a17ae | 87 | route_map_object_t type, void *object) |
f3ccedaa | 88 | { |
d62a17ae | 89 | struct prefix_list *plist; |
f3ccedaa | 90 | |
d62a17ae | 91 | if (type != RMAP_ISIS) |
92 | return RMAP_NOMATCH; | |
f3ccedaa | 93 | |
d62a17ae | 94 | plist = prefix_list_lookup(AFI_IP, (char *)rule); |
95 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
96 | return RMAP_MATCH; | |
f3ccedaa | 97 | |
d62a17ae | 98 | return RMAP_NOMATCH; |
f3ccedaa CF |
99 | } |
100 | ||
d62a17ae | 101 | static void *route_match_ip_address_prefix_list_compile(const char *arg) |
f3ccedaa | 102 | { |
d62a17ae | 103 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
104 | } |
105 | ||
d62a17ae | 106 | static void route_match_ip_address_prefix_list_free(void *rule) |
f3ccedaa | 107 | { |
d62a17ae | 108 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
109 | } |
110 | ||
d62a17ae | 111 | struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { |
112 | "ip address prefix-list", route_match_ip_address_prefix_list, | |
113 | route_match_ip_address_prefix_list_compile, | |
114 | route_match_ip_address_prefix_list_free}; | |
f3ccedaa CF |
115 | |
116 | /* ------------------------------------------------------------*/ | |
117 | ||
d62a17ae | 118 | static route_map_result_t route_match_ipv6_address(void *rule, |
123214ef | 119 | const struct prefix *prefix, |
d62a17ae | 120 | route_map_object_t type, |
121 | void *object) | |
eb5d44eb | 122 | { |
d62a17ae | 123 | struct access_list *alist; |
f390d2c7 | 124 | |
d62a17ae | 125 | if (type != RMAP_ISIS) |
126 | return RMAP_NOMATCH; | |
f3ccedaa | 127 | |
d62a17ae | 128 | alist = access_list_lookup(AFI_IP6, (char *)rule); |
129 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
130 | return RMAP_MATCH; | |
f3ccedaa | 131 | |
d62a17ae | 132 | return RMAP_NOMATCH; |
f3ccedaa CF |
133 | } |
134 | ||
d62a17ae | 135 | static void *route_match_ipv6_address_compile(const char *arg) |
f3ccedaa | 136 | { |
d62a17ae | 137 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
138 | } |
139 | ||
d62a17ae | 140 | static void route_match_ipv6_address_free(void *rule) |
f3ccedaa | 141 | { |
d62a17ae | 142 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
143 | } |
144 | ||
d62a17ae | 145 | static struct route_map_rule_cmd route_match_ipv6_address_cmd = { |
146 | "ipv6 address", route_match_ipv6_address, | |
147 | route_match_ipv6_address_compile, route_match_ipv6_address_free}; | |
f3ccedaa CF |
148 | |
149 | /* ------------------------------------------------------------*/ | |
150 | ||
151 | static route_map_result_t | |
123214ef | 152 | route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix, |
d62a17ae | 153 | route_map_object_t type, void *object) |
f3ccedaa | 154 | { |
d62a17ae | 155 | struct prefix_list *plist; |
f390d2c7 | 156 | |
d62a17ae | 157 | if (type != RMAP_ISIS) |
158 | return RMAP_NOMATCH; | |
f3ccedaa | 159 | |
d62a17ae | 160 | plist = prefix_list_lookup(AFI_IP6, (char *)rule); |
161 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
162 | return RMAP_MATCH; | |
f3ccedaa | 163 | |
d62a17ae | 164 | return RMAP_NOMATCH; |
f3ccedaa CF |
165 | } |
166 | ||
d62a17ae | 167 | static void *route_match_ipv6_address_prefix_list_compile(const char *arg) |
f3ccedaa | 168 | { |
d62a17ae | 169 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
170 | } |
171 | ||
d62a17ae | 172 | static void route_match_ipv6_address_prefix_list_free(void *rule) |
f3ccedaa | 173 | { |
d62a17ae | 174 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
175 | } |
176 | ||
d62a17ae | 177 | struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = { |
178 | "ipv6 address prefix-list", route_match_ipv6_address_prefix_list, | |
179 | route_match_ipv6_address_prefix_list_compile, | |
180 | route_match_ipv6_address_prefix_list_free}; | |
f3ccedaa CF |
181 | |
182 | /* ------------------------------------------------------------*/ | |
183 | ||
123214ef MS |
184 | static route_map_result_t route_set_metric(void *rule, |
185 | const struct prefix *prefix, | |
d62a17ae | 186 | route_map_object_t type, |
187 | void *object) | |
f3ccedaa | 188 | { |
d62a17ae | 189 | uint32_t *metric; |
190 | struct isis_ext_info *info; | |
f3ccedaa | 191 | |
d62a17ae | 192 | if (type == RMAP_ISIS) { |
193 | metric = rule; | |
194 | info = object; | |
f3ccedaa | 195 | |
d62a17ae | 196 | info->metric = *metric; |
197 | } | |
198 | return RMAP_OKAY; | |
eb5d44eb | 199 | } |
200 | ||
d62a17ae | 201 | static void *route_set_metric_compile(const char *arg) |
f3ccedaa | 202 | { |
d62a17ae | 203 | unsigned long metric; |
204 | char *endp; | |
205 | uint32_t *ret; | |
f3ccedaa | 206 | |
d62a17ae | 207 | metric = strtoul(arg, &endp, 10); |
208 | if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) | |
209 | return NULL; | |
f3ccedaa | 210 | |
d62a17ae | 211 | ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); |
212 | *ret = metric; | |
f3ccedaa | 213 | |
d62a17ae | 214 | return ret; |
f3ccedaa CF |
215 | } |
216 | ||
d62a17ae | 217 | static void route_set_metric_free(void *rule) |
eb5d44eb | 218 | { |
d62a17ae | 219 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
220 | } |
221 | ||
d62a17ae | 222 | static struct route_map_rule_cmd route_set_metric_cmd = { |
223 | "metric", route_set_metric, route_set_metric_compile, | |
224 | route_set_metric_free}; | |
225 | ||
226 | void isis_route_map_init(void) | |
f3ccedaa | 227 | { |
d62a17ae | 228 | route_map_init(); |
f3ccedaa | 229 | |
d62a17ae | 230 | route_map_match_ip_address_hook(generic_match_add); |
231 | route_map_no_match_ip_address_hook(generic_match_delete); | |
f3ccedaa | 232 | |
d62a17ae | 233 | route_map_match_ip_address_prefix_list_hook(generic_match_add); |
234 | route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); | |
f3ccedaa | 235 | |
d62a17ae | 236 | route_map_match_ipv6_address_hook(generic_match_add); |
237 | route_map_no_match_ipv6_address_hook(generic_match_delete); | |
f3ccedaa | 238 | |
d62a17ae | 239 | route_map_match_ipv6_address_prefix_list_hook(generic_match_add); |
240 | route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete); | |
f3ccedaa | 241 | |
d62a17ae | 242 | route_map_set_metric_hook(generic_set_add); |
243 | route_map_no_set_metric_hook(generic_set_delete); | |
f3ccedaa | 244 | |
d62a17ae | 245 | route_map_install_match(&route_match_ip_address_cmd); |
246 | route_map_install_match(&route_match_ip_address_prefix_list_cmd); | |
247 | route_map_install_match(&route_match_ipv6_address_cmd); | |
248 | route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); | |
249 | route_map_install_set(&route_set_metric_cmd); | |
eb5d44eb | 250 | } |