]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_routemap.c
Merge pull request #5280 from qlyoung/doc-clean-topotest-json
[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,
53 route_map_object_t type, void *object)
54 {
55 struct access_list *alist;
56
57 if (type != RMAP_ISIS)
58 return RMAP_NOMATCH;
59
60 alist = access_list_lookup(AFI_IP, (char *)rule);
61 if (access_list_apply(alist, prefix) != FILTER_DENY)
62 return RMAP_MATCH;
63
64 return RMAP_NOMATCH;
65 }
66
67 static void *route_match_ip_address_compile(const char *arg)
68 {
69 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
70 }
71
72 static void route_match_ip_address_free(void *rule)
73 {
74 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
75 }
76
77 static struct route_map_rule_cmd route_match_ip_address_cmd = {
78 "ip address", route_match_ip_address, route_match_ip_address_compile,
79 route_match_ip_address_free};
80
81 /* ------------------------------------------------------------*/
82
83 static enum route_map_cmd_result_t
84 route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
85 route_map_object_t type, void *object)
86 {
87 struct prefix_list *plist;
88
89 if (type != RMAP_ISIS)
90 return RMAP_NOMATCH;
91
92 plist = prefix_list_lookup(AFI_IP, (char *)rule);
93 if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
94 return RMAP_MATCH;
95
96 return RMAP_NOMATCH;
97 }
98
99 static void *route_match_ip_address_prefix_list_compile(const char *arg)
100 {
101 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
102 }
103
104 static void route_match_ip_address_prefix_list_free(void *rule)
105 {
106 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
107 }
108
109 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
110 "ip address prefix-list", route_match_ip_address_prefix_list,
111 route_match_ip_address_prefix_list_compile,
112 route_match_ip_address_prefix_list_free};
113
114 /* ------------------------------------------------------------*/
115
116 static enum route_map_cmd_result_t
117 route_match_ipv6_address(void *rule, const struct prefix *prefix,
118 route_map_object_t type, void *object)
119 {
120 struct access_list *alist;
121
122 if (type != RMAP_ISIS)
123 return RMAP_NOMATCH;
124
125 alist = access_list_lookup(AFI_IP6, (char *)rule);
126 if (access_list_apply(alist, prefix) != FILTER_DENY)
127 return RMAP_MATCH;
128
129 return RMAP_NOMATCH;
130 }
131
132 static void *route_match_ipv6_address_compile(const char *arg)
133 {
134 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
135 }
136
137 static void route_match_ipv6_address_free(void *rule)
138 {
139 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
140 }
141
142 static struct route_map_rule_cmd route_match_ipv6_address_cmd = {
143 "ipv6 address", route_match_ipv6_address,
144 route_match_ipv6_address_compile, route_match_ipv6_address_free};
145
146 /* ------------------------------------------------------------*/
147
148 static enum route_map_cmd_result_t
149 route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
150 route_map_object_t type, void *object)
151 {
152 struct prefix_list *plist;
153
154 if (type != RMAP_ISIS)
155 return RMAP_NOMATCH;
156
157 plist = prefix_list_lookup(AFI_IP6, (char *)rule);
158 if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
159 return RMAP_MATCH;
160
161 return RMAP_NOMATCH;
162 }
163
164 static void *route_match_ipv6_address_prefix_list_compile(const char *arg)
165 {
166 return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
167 }
168
169 static void route_match_ipv6_address_prefix_list_free(void *rule)
170 {
171 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
172 }
173
174 struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
175 "ipv6 address prefix-list", route_match_ipv6_address_prefix_list,
176 route_match_ipv6_address_prefix_list_compile,
177 route_match_ipv6_address_prefix_list_free};
178
179 /* ------------------------------------------------------------*/
180
181 static enum route_map_cmd_result_t
182 route_set_metric(void *rule, const struct prefix *prefix,
183 route_map_object_t type, void *object)
184 {
185 uint32_t *metric;
186 struct isis_ext_info *info;
187
188 if (type == RMAP_ISIS) {
189 metric = rule;
190 info = object;
191
192 info->metric = *metric;
193 }
194 return RMAP_OKAY;
195 }
196
197 static void *route_set_metric_compile(const char *arg)
198 {
199 unsigned long metric;
200 char *endp;
201 uint32_t *ret;
202
203 metric = strtoul(arg, &endp, 10);
204 if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC)
205 return NULL;
206
207 ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret));
208 *ret = metric;
209
210 return ret;
211 }
212
213 static void route_set_metric_free(void *rule)
214 {
215 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
216 }
217
218 static struct route_map_rule_cmd route_set_metric_cmd = {
219 "metric", route_set_metric, route_set_metric_compile,
220 route_set_metric_free};
221
222 void isis_route_map_init(void)
223 {
224 route_map_init();
225
226 route_map_match_ip_address_hook(generic_match_add);
227 route_map_no_match_ip_address_hook(generic_match_delete);
228
229 route_map_match_ip_address_prefix_list_hook(generic_match_add);
230 route_map_no_match_ip_address_prefix_list_hook(generic_match_delete);
231
232 route_map_match_ipv6_address_hook(generic_match_add);
233 route_map_no_match_ipv6_address_hook(generic_match_delete);
234
235 route_map_match_ipv6_address_prefix_list_hook(generic_match_add);
236 route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete);
237
238 route_map_set_metric_hook(generic_set_add);
239 route_map_no_set_metric_hook(generic_set_delete);
240
241 route_map_install_match(&route_match_ip_address_cmd);
242 route_map_install_match(&route_match_ip_address_prefix_list_cmd);
243 route_map_install_match(&route_match_ipv6_address_cmd);
244 route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
245 route_map_install_set(&route_set_metric_cmd);
246 }