]> git.proxmox.com Git - mirror_frr.git/blame - lib/if_rmap.c
ldpd: use red-black trees to store 'tnbr' elements
[mirror_frr.git] / lib / if_rmap.c
CommitLineData
718e3744 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"
0750d21f 28#include "if_rmap.h"
718e3744 29
4a1ab8e4
DL
30DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map")
31DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name")
32
718e3744 33struct hash *ifrmaphash;
34
35/* Hook functions. */
8cc4198f 36static void (*if_rmap_add_hook) (struct if_rmap *) = NULL;
37static void (*if_rmap_delete_hook) (struct if_rmap *) = NULL;
6b0655a2 38
8cc4198f 39static struct if_rmap *
40if_rmap_new (void)
718e3744 41{
42 struct if_rmap *new;
43
44 new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap));
45
46 return new;
47}
48
8cc4198f 49static void
718e3744 50if_rmap_free (struct if_rmap *if_rmap)
51{
52 if (if_rmap->ifname)
0241684e 53 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->ifname);
718e3744 54
55 if (if_rmap->routemap[IF_RMAP_IN])
0241684e 56 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
718e3744 57 if (if_rmap->routemap[IF_RMAP_OUT])
0241684e 58 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
718e3744 59
60 XFREE (MTYPE_IF_RMAP, if_rmap);
61}
62
63struct if_rmap *
9035efaa 64if_rmap_lookup (const char *ifname)
718e3744 65{
66 struct if_rmap key;
67 struct if_rmap *if_rmap;
68
9035efaa 69 /* temporary copy */
3a7c85d1 70 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
718e3744 71
72 if_rmap = hash_lookup (ifrmaphash, &key);
73
3a7c85d1
DS
74 if (key.ifname)
75 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
76
718e3744 77 return if_rmap;
78}
79
80void
81if_rmap_hook_add (void (*func) (struct if_rmap *))
82{
83 if_rmap_add_hook = func;
84}
85
86void
87if_rmap_hook_delete (void (*func) (struct if_rmap *))
88{
89 if_rmap_delete_hook = func;
90}
91
8cc4198f 92static void *
93if_rmap_hash_alloc (void *arg)
718e3744 94{
24873f0c 95 struct if_rmap *ifarg = (struct if_rmap *)arg;
718e3744 96 struct if_rmap *if_rmap;
97
98 if_rmap = if_rmap_new ();
0241684e 99 if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname);
718e3744 100
101 return if_rmap;
102}
103
8cc4198f 104static struct if_rmap *
9035efaa 105if_rmap_get (const char *ifname)
718e3744 106{
107 struct if_rmap key;
24873f0c 108 struct if_rmap *ret;
718e3744 109
9035efaa 110 /* temporary copy */
3a7c85d1 111 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
718e3744 112
24873f0c 113 ret = hash_get (ifrmaphash, &key, if_rmap_hash_alloc);
3a7c85d1 114
24873f0c
DS
115 if (key.ifname)
116 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
117
118 return ret;
718e3744 119}
120
8cc4198f 121static unsigned int
122if_rmap_hash_make (void *data)
718e3744 123{
6392aa83 124 const struct if_rmap *if_rmap = data;
718e3744 125
6392aa83 126 return string_hash_make (if_rmap->ifname);
718e3744 127}
128
8cc4198f 129static int
ffe11cfb 130if_rmap_hash_cmp (const void *arg1, const void* arg2)
718e3744 131{
ffe11cfb
SH
132 const struct if_rmap *if_rmap1 = arg1;
133 const struct if_rmap *if_rmap2 = arg2;
134
135 return strcmp (if_rmap1->ifname, if_rmap2->ifname) == 0;
718e3744 136}
6b0655a2 137
8cc4198f 138static struct if_rmap *
9035efaa 139if_rmap_set (const char *ifname, enum if_rmap_type type,
140 const char *routemap_name)
718e3744 141{
142 struct if_rmap *if_rmap;
143
144 if_rmap = if_rmap_get (ifname);
145
146 if (type == IF_RMAP_IN)
147 {
148 if (if_rmap->routemap[IF_RMAP_IN])
0241684e 149 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
150 if_rmap->routemap[IF_RMAP_IN]
151 = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name);
718e3744 152 }
153 if (type == IF_RMAP_OUT)
154 {
155 if (if_rmap->routemap[IF_RMAP_OUT])
0241684e 156 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
157 if_rmap->routemap[IF_RMAP_OUT]
158 = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name);
718e3744 159 }
160
161 if (if_rmap_add_hook)
162 (*if_rmap_add_hook) (if_rmap);
163
164 return if_rmap;
165}
166
8cc4198f 167static int
9035efaa 168if_rmap_unset (const char *ifname, enum if_rmap_type type,
169 const char *routemap_name)
718e3744 170{
171 struct if_rmap *if_rmap;
172
173 if_rmap = if_rmap_lookup (ifname);
174 if (!if_rmap)
175 return 0;
176
177 if (type == IF_RMAP_IN)
178 {
179 if (!if_rmap->routemap[IF_RMAP_IN])
180 return 0;
181 if (strcmp (if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0)
182 return 0;
183
0241684e 184 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
718e3744 185 if_rmap->routemap[IF_RMAP_IN] = NULL;
186 }
187
188 if (type == IF_RMAP_OUT)
189 {
190 if (!if_rmap->routemap[IF_RMAP_OUT])
191 return 0;
192 if (strcmp (if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0)
193 return 0;
194
0241684e 195 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
718e3744 196 if_rmap->routemap[IF_RMAP_OUT] = NULL;
197 }
198
199 if (if_rmap_delete_hook)
200 (*if_rmap_delete_hook) (if_rmap);
201
202 if (if_rmap->routemap[IF_RMAP_IN] == NULL &&
203 if_rmap->routemap[IF_RMAP_OUT] == NULL)
204 {
205 hash_release (ifrmaphash, if_rmap);
206 if_rmap_free (if_rmap);
207 }
208
209 return 1;
210}
211
0750d21f 212DEFUN (if_rmap,
213 if_rmap_cmd,
718e3744 214 "route-map RMAP_NAME (in|out) IFNAME",
215 "Route map set\n"
216 "Route map name\n"
217 "Route map set for input filtering\n"
218 "Route map set for output filtering\n"
219 "Route map interface name\n")
220{
221 enum if_rmap_type type;
718e3744 222
223 if (strncmp (argv[1], "i", 1) == 0)
224 type = IF_RMAP_IN;
225 else if (strncmp (argv[1], "o", 1) == 0)
226 type = IF_RMAP_OUT;
227 else
228 {
229 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
230 return CMD_WARNING;
231 }
232
9206f9ec 233 if_rmap_set (argv[2], type, argv[0]);
718e3744 234
235 return CMD_SUCCESS;
4f849479 236}
237
238ALIAS (if_rmap,
239 if_ipv6_rmap_cmd,
240 "route-map RMAP_NAME (in|out) IFNAME",
241 "Route map set\n"
242 "Route map name\n"
243 "Route map set for input filtering\n"
244 "Route map set for output filtering\n"
245 "Route map interface name\n")
718e3744 246
0750d21f 247DEFUN (no_if_rmap,
248 no_if_rmap_cmd,
718e3744 249 "no route-map ROUTEMAP_NAME (in|out) IFNAME",
250 NO_STR
251 "Route map unset\n"
252 "Route map name\n"
253 "Route map for input filtering\n"
254 "Route map for output filtering\n"
255 "Route map interface name\n")
256{
257 int ret;
258 enum if_rmap_type type;
259
260 if (strncmp (argv[1], "i", 1) == 0)
261 type = IF_RMAP_IN;
262 else if (strncmp (argv[1], "o", 1) == 0)
263 type = IF_RMAP_OUT;
264 else
265 {
266 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
267 return CMD_WARNING;
268 }
269
270 ret = if_rmap_unset (argv[2], type, argv[0]);
271 if (! ret)
272 {
273 vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE);
274 return CMD_WARNING;
275 }
276 return CMD_SUCCESS;
4f849479 277}
278
279ALIAS (no_if_rmap,
280 no_if_ipv6_rmap_cmd,
281 "no route-map ROUTEMAP_NAME (in|out) IFNAME",
282 NO_STR
283 "Route map unset\n"
284 "Route map name\n"
285 "Route map for input filtering\n"
286 "Route map for output filtering\n"
287 "Route map interface name\n")
6b0655a2 288
718e3744 289/* Configuration write function. */
290int
291config_write_if_rmap (struct vty *vty)
292{
8c328f11 293 unsigned int i;
718e3744 294 struct hash_backet *mp;
295 int write = 0;
296
297 for (i = 0; i < ifrmaphash->size; i++)
298 for (mp = ifrmaphash->index[i]; mp; mp = mp->next)
299 {
300 struct if_rmap *if_rmap;
301
302 if_rmap = mp->data;
303
304 if (if_rmap->routemap[IF_RMAP_IN])
305 {
306 vty_out (vty, " route-map %s in %s%s",
307 if_rmap->routemap[IF_RMAP_IN],
308 if_rmap->ifname,
309 VTY_NEWLINE);
310 write++;
311 }
312
313 if (if_rmap->routemap[IF_RMAP_OUT])
314 {
315 vty_out (vty, " route-map %s out %s%s",
316 if_rmap->routemap[IF_RMAP_OUT],
317 if_rmap->ifname,
318 VTY_NEWLINE);
319 write++;
320 }
321 }
322 return write;
323}
324
325void
326if_rmap_reset ()
327{
328 hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free);
329}
330
331void
0750d21f 332if_rmap_init (int node)
718e3744 333{
334 ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
0750d21f 335 if (node == RIPNG_NODE) {
4f849479 336 install_element (RIPNG_NODE, &if_ipv6_rmap_cmd);
337 install_element (RIPNG_NODE, &no_if_ipv6_rmap_cmd);
338 } else if (node == RIP_NODE) {
339 install_element (RIP_NODE, &if_rmap_cmd);
340 install_element (RIP_NODE, &no_if_rmap_cmd);
0750d21f 341 }
718e3744 342}