]> git.proxmox.com Git - mirror_frr.git/blob - lib/if_rmap.c
lib: Fixup of NULL calls to XSTRDUP
[mirror_frr.git] / lib / if_rmap.c
1 /* route-map for interface.
2 * Copyright (C) 1999 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra 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
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 #include "hash.h"
25 #include "command.h"
26 #include "memory.h"
27 #include "if.h"
28 #include "if_rmap.h"
29
30 struct hash *ifrmaphash;
31
32 /* Hook functions. */
33 static void (*if_rmap_add_hook) (struct if_rmap *) = NULL;
34 static void (*if_rmap_delete_hook) (struct if_rmap *) = NULL;
35
36 static struct if_rmap *
37 if_rmap_new (void)
38 {
39 struct if_rmap *new;
40
41 new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap));
42
43 return new;
44 }
45
46 static void
47 if_rmap_free (struct if_rmap *if_rmap)
48 {
49 if (if_rmap->ifname)
50 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->ifname);
51
52 if (if_rmap->routemap[IF_RMAP_IN])
53 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
54 if (if_rmap->routemap[IF_RMAP_OUT])
55 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
56
57 XFREE (MTYPE_IF_RMAP, if_rmap);
58 }
59
60 struct if_rmap *
61 if_rmap_lookup (const char *ifname)
62 {
63 struct if_rmap key;
64 struct if_rmap *if_rmap;
65
66 /* temporary copy */
67 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
68
69 if_rmap = hash_lookup (ifrmaphash, &key);
70
71 if (key.ifname)
72 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
73
74 return if_rmap;
75 }
76
77 void
78 if_rmap_hook_add (void (*func) (struct if_rmap *))
79 {
80 if_rmap_add_hook = func;
81 }
82
83 void
84 if_rmap_hook_delete (void (*func) (struct if_rmap *))
85 {
86 if_rmap_delete_hook = func;
87 }
88
89 static void *
90 if_rmap_hash_alloc (void *arg)
91 {
92 struct if_rmap *ifarg = (struct if_rmap *)arg;
93 struct if_rmap *if_rmap;
94
95 if_rmap = if_rmap_new ();
96 if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname);
97
98 return if_rmap;
99 }
100
101 static struct if_rmap *
102 if_rmap_get (const char *ifname)
103 {
104 struct if_rmap key;
105 struct if_rmap *ret;
106
107 /* temporary copy */
108 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
109
110 ret = hash_get (ifrmaphash, &key, if_rmap_hash_alloc);
111
112 if (key.ifname)
113 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
114
115 return ret;
116 }
117
118 static unsigned int
119 if_rmap_hash_make (void *data)
120 {
121 const struct if_rmap *if_rmap = data;
122
123 return string_hash_make (if_rmap->ifname);
124 }
125
126 static int
127 if_rmap_hash_cmp (const void *arg1, const void* arg2)
128 {
129 const struct if_rmap *if_rmap1 = arg1;
130 const struct if_rmap *if_rmap2 = arg2;
131
132 return strcmp (if_rmap1->ifname, if_rmap2->ifname) == 0;
133 }
134
135 static struct if_rmap *
136 if_rmap_set (const char *ifname, enum if_rmap_type type,
137 const char *routemap_name)
138 {
139 struct if_rmap *if_rmap;
140
141 if_rmap = if_rmap_get (ifname);
142
143 if (type == IF_RMAP_IN)
144 {
145 if (if_rmap->routemap[IF_RMAP_IN])
146 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
147 if_rmap->routemap[IF_RMAP_IN]
148 = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name);
149 }
150 if (type == IF_RMAP_OUT)
151 {
152 if (if_rmap->routemap[IF_RMAP_OUT])
153 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
154 if_rmap->routemap[IF_RMAP_OUT]
155 = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name);
156 }
157
158 if (if_rmap_add_hook)
159 (*if_rmap_add_hook) (if_rmap);
160
161 return if_rmap;
162 }
163
164 static int
165 if_rmap_unset (const char *ifname, enum if_rmap_type type,
166 const char *routemap_name)
167 {
168 struct if_rmap *if_rmap;
169
170 if_rmap = if_rmap_lookup (ifname);
171 if (!if_rmap)
172 return 0;
173
174 if (type == IF_RMAP_IN)
175 {
176 if (!if_rmap->routemap[IF_RMAP_IN])
177 return 0;
178 if (strcmp (if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0)
179 return 0;
180
181 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
182 if_rmap->routemap[IF_RMAP_IN] = NULL;
183 }
184
185 if (type == IF_RMAP_OUT)
186 {
187 if (!if_rmap->routemap[IF_RMAP_OUT])
188 return 0;
189 if (strcmp (if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0)
190 return 0;
191
192 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
193 if_rmap->routemap[IF_RMAP_OUT] = NULL;
194 }
195
196 if (if_rmap_delete_hook)
197 (*if_rmap_delete_hook) (if_rmap);
198
199 if (if_rmap->routemap[IF_RMAP_IN] == NULL &&
200 if_rmap->routemap[IF_RMAP_OUT] == NULL)
201 {
202 hash_release (ifrmaphash, if_rmap);
203 if_rmap_free (if_rmap);
204 }
205
206 return 1;
207 }
208
209 DEFUN (if_rmap,
210 if_rmap_cmd,
211 "route-map RMAP_NAME (in|out) IFNAME",
212 "Route map set\n"
213 "Route map name\n"
214 "Route map set for input filtering\n"
215 "Route map set for output filtering\n"
216 "Route map interface name\n")
217 {
218 enum if_rmap_type type;
219
220 if (strncmp (argv[1], "i", 1) == 0)
221 type = IF_RMAP_IN;
222 else if (strncmp (argv[1], "o", 1) == 0)
223 type = IF_RMAP_OUT;
224 else
225 {
226 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
227 return CMD_WARNING;
228 }
229
230 if_rmap_set (argv[2], type, argv[0]);
231
232 return CMD_SUCCESS;
233 }
234
235 ALIAS (if_rmap,
236 if_ipv6_rmap_cmd,
237 "route-map RMAP_NAME (in|out) IFNAME",
238 "Route map set\n"
239 "Route map name\n"
240 "Route map set for input filtering\n"
241 "Route map set for output filtering\n"
242 "Route map interface name\n")
243
244 DEFUN (no_if_rmap,
245 no_if_rmap_cmd,
246 "no route-map ROUTEMAP_NAME (in|out) IFNAME",
247 NO_STR
248 "Route map unset\n"
249 "Route map name\n"
250 "Route map for input filtering\n"
251 "Route map for output filtering\n"
252 "Route map interface name\n")
253 {
254 int ret;
255 enum if_rmap_type type;
256
257 if (strncmp (argv[1], "i", 1) == 0)
258 type = IF_RMAP_IN;
259 else if (strncmp (argv[1], "o", 1) == 0)
260 type = IF_RMAP_OUT;
261 else
262 {
263 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
264 return CMD_WARNING;
265 }
266
267 ret = if_rmap_unset (argv[2], type, argv[0]);
268 if (! ret)
269 {
270 vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE);
271 return CMD_WARNING;
272 }
273 return CMD_SUCCESS;
274 }
275
276 ALIAS (no_if_rmap,
277 no_if_ipv6_rmap_cmd,
278 "no route-map ROUTEMAP_NAME (in|out) IFNAME",
279 NO_STR
280 "Route map unset\n"
281 "Route map name\n"
282 "Route map for input filtering\n"
283 "Route map for output filtering\n"
284 "Route map interface name\n")
285
286 /* Configuration write function. */
287 int
288 config_write_if_rmap (struct vty *vty)
289 {
290 unsigned int i;
291 struct hash_backet *mp;
292 int write = 0;
293
294 for (i = 0; i < ifrmaphash->size; i++)
295 for (mp = ifrmaphash->index[i]; mp; mp = mp->next)
296 {
297 struct if_rmap *if_rmap;
298
299 if_rmap = mp->data;
300
301 if (if_rmap->routemap[IF_RMAP_IN])
302 {
303 vty_out (vty, " route-map %s in %s%s",
304 if_rmap->routemap[IF_RMAP_IN],
305 if_rmap->ifname,
306 VTY_NEWLINE);
307 write++;
308 }
309
310 if (if_rmap->routemap[IF_RMAP_OUT])
311 {
312 vty_out (vty, " route-map %s out %s%s",
313 if_rmap->routemap[IF_RMAP_OUT],
314 if_rmap->ifname,
315 VTY_NEWLINE);
316 write++;
317 }
318 }
319 return write;
320 }
321
322 void
323 if_rmap_reset ()
324 {
325 hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free);
326 }
327
328 void
329 if_rmap_init (int node)
330 {
331 ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
332 if (node == RIPNG_NODE) {
333 install_element (RIPNG_NODE, &if_ipv6_rmap_cmd);
334 install_element (RIPNG_NODE, &no_if_ipv6_rmap_cmd);
335 } else if (node == RIP_NODE) {
336 install_element (RIP_NODE, &if_rmap_cmd);
337 install_element (RIP_NODE, &no_if_rmap_cmd);
338 }
339 }