]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_routemap.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / isisd / isis_routemap.c
1 /*
2 * IS-IS Rout(e)ing protocol - isis_routemap.c
3 *
4 * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
5 *
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)
9 * any later version.
10 *
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
14 * more details.
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
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "filter.h"
25 #include "hash.h"
26 #include "if.h"
27 #include "linklist.h"
28 #include "log.h"
29 #include "memory.h"
30 #include "prefix.h"
31 #include "plist.h"
32 #include "routemap.h"
33 #include "table.h"
34 #include "thread.h"
35 #include "vty.h"
36
37 #include "isis_constants.h"
38 #include "isis_common.h"
39 #include "isis_flags.h"
40 #include "isisd.h"
41 #include "isis_misc.h"
42 #include "isis_adjacency.h"
43 #include "isis_circuit.h"
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"
49 #include "isis_routemap.h"
50
51 static enum route_map_cmd_result_t
52 route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
53 {
54 struct access_list *alist;
55
56 alist = access_list_lookup(AFI_IP, (char *)rule);
57 if (access_list_apply(alist, prefix) != FILTER_DENY)
58 return RMAP_MATCH;
59
60 return RMAP_NOMATCH;
61 }
62
63 static void *route_match_ip_address_compile(const char *arg)
64 {
65 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
66 }
67
68 static void route_match_ip_address_free(void *rule)
69 {
70 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
71 }
72
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 };
79
80 /* ------------------------------------------------------------*/
81
82 static enum route_map_cmd_result_t
83 route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
84 void *object)
85 {
86 struct prefix_list *plist;
87
88 plist = prefix_list_lookup(AFI_IP, (char *)rule);
89 if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
90 return RMAP_MATCH;
91
92 return RMAP_NOMATCH;
93 }
94
95 static void *route_match_ip_address_prefix_list_compile(const char *arg)
96 {
97 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
98 }
99
100 static void route_match_ip_address_prefix_list_free(void *rule)
101 {
102 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
103 }
104
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,
109 route_match_ip_address_prefix_list_compile,
110 route_match_ip_address_prefix_list_free
111 };
112
113 /* ------------------------------------------------------------*/
114
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
144 static enum route_map_cmd_result_t
145 route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object)
146 {
147 struct access_list *alist;
148
149 alist = access_list_lookup(AFI_IP6, (char *)rule);
150 if (access_list_apply(alist, prefix) != FILTER_DENY)
151 return RMAP_MATCH;
152
153 return RMAP_NOMATCH;
154 }
155
156 static void *route_match_ipv6_address_compile(const char *arg)
157 {
158 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
159 }
160
161 static void route_match_ipv6_address_free(void *rule)
162 {
163 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
164 }
165
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 };
172
173 /* ------------------------------------------------------------*/
174
175 static enum route_map_cmd_result_t
176 route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
177 void *object)
178 {
179 struct prefix_list *plist;
180
181 plist = prefix_list_lookup(AFI_IP6, (char *)rule);
182 if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
183 return RMAP_MATCH;
184
185 return RMAP_NOMATCH;
186 }
187
188 static void *route_match_ipv6_address_prefix_list_compile(const char *arg)
189 {
190 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
191 }
192
193 static void route_match_ipv6_address_prefix_list_free(void *rule)
194 {
195 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
196 }
197
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,
202 route_match_ipv6_address_prefix_list_compile,
203 route_match_ipv6_address_prefix_list_free
204 };
205
206 /* ------------------------------------------------------------*/
207
208 static enum route_map_cmd_result_t
209 route_set_metric(void *rule, const struct prefix *prefix, void *object)
210 {
211 uint32_t *metric;
212 struct isis_ext_info *info;
213
214 metric = rule;
215 info = object;
216
217 info->metric = *metric;
218
219 return RMAP_OKAY;
220 }
221
222 static void *route_set_metric_compile(const char *arg)
223 {
224 unsigned long metric;
225 char *endp;
226 uint32_t *ret;
227
228 metric = strtoul(arg, &endp, 10);
229 if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC)
230 return NULL;
231
232 ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret));
233 *ret = metric;
234
235 return ret;
236 }
237
238 static void route_set_metric_free(void *rule)
239 {
240 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
241 }
242
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 };
249
250 void isis_route_map_init(void)
251 {
252 route_map_init();
253
254 route_map_match_ip_address_hook(generic_match_add);
255 route_map_no_match_ip_address_hook(generic_match_delete);
256
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);
259
260 route_map_match_ipv6_address_hook(generic_match_add);
261 route_map_no_match_ipv6_address_hook(generic_match_delete);
262
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);
265
266 route_map_match_tag_hook(generic_match_add);
267 route_map_no_match_tag_hook(generic_match_delete);
268
269 route_map_set_metric_hook(generic_set_add);
270 route_map_no_set_metric_hook(generic_set_delete);
271
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);
276 route_map_install_match(&route_match_tag_cmd);
277 route_map_install_set(&route_set_metric_cmd);
278 }