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