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