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