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