]>
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 "isisd.h" |
41 | #include "isis_misc.h" | |
42 | #include "isis_adjacency.h" | |
43 | #include "isis_circuit.h" | |
eb5d44eb | 44 | #include "isis_pdu.h" |
45 | #include "isis_lsp.h" | |
46 | #include "isis_spf.h" | |
47 | #include "isis_route.h" | |
48 | #include "isis_zebra.h" | |
f3ccedaa | 49 | #include "isis_routemap.h" |
eb5d44eb | 50 | |
b68885f9 | 51 | static enum route_map_cmd_result_t |
1782514f | 52 | route_match_ip_address(void *rule, const struct prefix *prefix, void *object) |
f3ccedaa | 53 | { |
d62a17ae | 54 | struct access_list *alist; |
eb5d44eb | 55 | |
d62a17ae | 56 | alist = access_list_lookup(AFI_IP, (char *)rule); |
57 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
58 | return RMAP_MATCH; | |
41b36e90 | 59 | |
d62a17ae | 60 | return RMAP_NOMATCH; |
f3ccedaa CF |
61 | } |
62 | ||
d62a17ae | 63 | static void *route_match_ip_address_compile(const char *arg) |
f3ccedaa | 64 | { |
d62a17ae | 65 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
66 | } |
67 | ||
d62a17ae | 68 | static void route_match_ip_address_free(void *rule) |
f3ccedaa | 69 | { |
d62a17ae | 70 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
71 | } |
72 | ||
364deb04 DL |
73 | static const struct route_map_rule_cmd route_match_ip_address_cmd = { |
74 | "ip address", | |
75 | route_match_ip_address, | |
76 | route_match_ip_address_compile, | |
77 | route_match_ip_address_free | |
78 | }; | |
f3ccedaa CF |
79 | |
80 | /* ------------------------------------------------------------*/ | |
81 | ||
b68885f9 | 82 | static enum route_map_cmd_result_t |
123214ef | 83 | route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix, |
1782514f | 84 | void *object) |
f3ccedaa | 85 | { |
d62a17ae | 86 | struct prefix_list *plist; |
f3ccedaa | 87 | |
d62a17ae | 88 | plist = prefix_list_lookup(AFI_IP, (char *)rule); |
89 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
90 | return RMAP_MATCH; | |
f3ccedaa | 91 | |
d62a17ae | 92 | return RMAP_NOMATCH; |
f3ccedaa CF |
93 | } |
94 | ||
d62a17ae | 95 | static void *route_match_ip_address_prefix_list_compile(const char *arg) |
f3ccedaa | 96 | { |
d62a17ae | 97 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
98 | } |
99 | ||
d62a17ae | 100 | static void route_match_ip_address_prefix_list_free(void *rule) |
f3ccedaa | 101 | { |
d62a17ae | 102 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
103 | } |
104 | ||
364deb04 DL |
105 | static const struct route_map_rule_cmd |
106 | route_match_ip_address_prefix_list_cmd = { | |
107 | "ip address prefix-list", | |
108 | route_match_ip_address_prefix_list, | |
d62a17ae | 109 | route_match_ip_address_prefix_list_compile, |
364deb04 DL |
110 | route_match_ip_address_prefix_list_free |
111 | }; | |
f3ccedaa CF |
112 | |
113 | /* ------------------------------------------------------------*/ | |
114 | ||
3b1e3aab EA |
115 | /* `match tag TAG' */ |
116 | /* Match function return 1 if match is success else return zero. */ | |
117 | static enum route_map_cmd_result_t | |
118 | route_match_tag(void *rule, const struct prefix *p, void *object) | |
119 | { | |
120 | route_tag_t *tag; | |
121 | struct isis_ext_info *info; | |
122 | route_tag_t info_tag; | |
123 | ||
124 | tag = rule; | |
125 | info = object; | |
126 | ||
127 | info_tag = info->tag; | |
128 | if (info_tag == *tag) | |
129 | return RMAP_MATCH; | |
130 | else | |
131 | return RMAP_NOMATCH; | |
132 | } | |
133 | ||
134 | /* Route map commands for tag matching. */ | |
135 | static const struct route_map_rule_cmd route_match_tag_cmd = { | |
136 | "tag", | |
137 | route_match_tag, | |
138 | route_map_rule_tag_compile, | |
139 | route_map_rule_tag_free, | |
140 | }; | |
141 | ||
142 | /* ------------------------------------------------------------*/ | |
143 | ||
b68885f9 | 144 | static enum route_map_cmd_result_t |
1782514f | 145 | route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object) |
eb5d44eb | 146 | { |
d62a17ae | 147 | struct access_list *alist; |
f390d2c7 | 148 | |
d62a17ae | 149 | alist = access_list_lookup(AFI_IP6, (char *)rule); |
150 | if (access_list_apply(alist, prefix) != FILTER_DENY) | |
151 | return RMAP_MATCH; | |
f3ccedaa | 152 | |
d62a17ae | 153 | return RMAP_NOMATCH; |
f3ccedaa CF |
154 | } |
155 | ||
d62a17ae | 156 | static void *route_match_ipv6_address_compile(const char *arg) |
f3ccedaa | 157 | { |
d62a17ae | 158 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
159 | } |
160 | ||
d62a17ae | 161 | static void route_match_ipv6_address_free(void *rule) |
f3ccedaa | 162 | { |
d62a17ae | 163 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
164 | } |
165 | ||
364deb04 DL |
166 | static const struct route_map_rule_cmd route_match_ipv6_address_cmd = { |
167 | "ipv6 address", | |
168 | route_match_ipv6_address, | |
169 | route_match_ipv6_address_compile, | |
170 | route_match_ipv6_address_free | |
171 | }; | |
f3ccedaa CF |
172 | |
173 | /* ------------------------------------------------------------*/ | |
174 | ||
b68885f9 | 175 | static enum route_map_cmd_result_t |
123214ef | 176 | route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix, |
1782514f | 177 | void *object) |
f3ccedaa | 178 | { |
d62a17ae | 179 | struct prefix_list *plist; |
f390d2c7 | 180 | |
d62a17ae | 181 | plist = prefix_list_lookup(AFI_IP6, (char *)rule); |
182 | if (prefix_list_apply(plist, prefix) != PREFIX_DENY) | |
183 | return RMAP_MATCH; | |
f3ccedaa | 184 | |
d62a17ae | 185 | return RMAP_NOMATCH; |
f3ccedaa CF |
186 | } |
187 | ||
d62a17ae | 188 | static void *route_match_ipv6_address_prefix_list_compile(const char *arg) |
f3ccedaa | 189 | { |
d62a17ae | 190 | return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); |
f3ccedaa CF |
191 | } |
192 | ||
d62a17ae | 193 | static void route_match_ipv6_address_prefix_list_free(void *rule) |
f3ccedaa | 194 | { |
d62a17ae | 195 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
196 | } |
197 | ||
364deb04 DL |
198 | static const struct route_map_rule_cmd |
199 | route_match_ipv6_address_prefix_list_cmd = { | |
200 | "ipv6 address prefix-list", | |
201 | route_match_ipv6_address_prefix_list, | |
d62a17ae | 202 | route_match_ipv6_address_prefix_list_compile, |
364deb04 DL |
203 | route_match_ipv6_address_prefix_list_free |
204 | }; | |
f3ccedaa CF |
205 | |
206 | /* ------------------------------------------------------------*/ | |
207 | ||
b68885f9 | 208 | static enum route_map_cmd_result_t |
1782514f | 209 | route_set_metric(void *rule, const struct prefix *prefix, void *object) |
f3ccedaa | 210 | { |
d62a17ae | 211 | uint32_t *metric; |
212 | struct isis_ext_info *info; | |
f3ccedaa | 213 | |
1782514f DS |
214 | metric = rule; |
215 | info = object; | |
216 | ||
217 | info->metric = *metric; | |
f3ccedaa | 218 | |
d62a17ae | 219 | return RMAP_OKAY; |
eb5d44eb | 220 | } |
221 | ||
d62a17ae | 222 | static void *route_set_metric_compile(const char *arg) |
f3ccedaa | 223 | { |
d62a17ae | 224 | unsigned long metric; |
225 | char *endp; | |
226 | uint32_t *ret; | |
f3ccedaa | 227 | |
d62a17ae | 228 | metric = strtoul(arg, &endp, 10); |
229 | if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) | |
230 | return NULL; | |
f3ccedaa | 231 | |
d62a17ae | 232 | ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); |
233 | *ret = metric; | |
f3ccedaa | 234 | |
d62a17ae | 235 | return ret; |
f3ccedaa CF |
236 | } |
237 | ||
d62a17ae | 238 | static void route_set_metric_free(void *rule) |
eb5d44eb | 239 | { |
d62a17ae | 240 | XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); |
f3ccedaa CF |
241 | } |
242 | ||
364deb04 DL |
243 | static const struct route_map_rule_cmd route_set_metric_cmd = { |
244 | "metric", | |
245 | route_set_metric, | |
246 | route_set_metric_compile, | |
247 | route_set_metric_free | |
248 | }; | |
d62a17ae | 249 | |
250 | void isis_route_map_init(void) | |
f3ccedaa | 251 | { |
d62a17ae | 252 | route_map_init(); |
f3ccedaa | 253 | |
d62a17ae | 254 | route_map_match_ip_address_hook(generic_match_add); |
255 | route_map_no_match_ip_address_hook(generic_match_delete); | |
f3ccedaa | 256 | |
d62a17ae | 257 | route_map_match_ip_address_prefix_list_hook(generic_match_add); |
258 | route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); | |
f3ccedaa | 259 | |
d62a17ae | 260 | route_map_match_ipv6_address_hook(generic_match_add); |
261 | route_map_no_match_ipv6_address_hook(generic_match_delete); | |
f3ccedaa | 262 | |
d62a17ae | 263 | route_map_match_ipv6_address_prefix_list_hook(generic_match_add); |
264 | route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete); | |
f3ccedaa | 265 | |
3b1e3aab EA |
266 | route_map_match_tag_hook(generic_match_add); |
267 | route_map_no_match_tag_hook(generic_match_delete); | |
268 | ||
d62a17ae | 269 | route_map_set_metric_hook(generic_set_add); |
270 | route_map_no_set_metric_hook(generic_set_delete); | |
f3ccedaa | 271 | |
d62a17ae | 272 | route_map_install_match(&route_match_ip_address_cmd); |
273 | route_map_install_match(&route_match_ip_address_prefix_list_cmd); | |
274 | route_map_install_match(&route_match_ipv6_address_cmd); | |
275 | route_map_install_match(&route_match_ipv6_address_prefix_list_cmd); | |
3b1e3aab | 276 | route_map_install_match(&route_match_tag_cmd); |
d62a17ae | 277 | route_map_install_set(&route_set_metric_cmd); |
eb5d44eb | 278 | } |