]> git.proxmox.com Git - mirror_frr.git/blob - lib/if_rmap.c
7d049b87207d3e05e48370e6c0d3f3da045fcfc7
[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 \f
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 = (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 static void *
87 if_rmap_hash_alloc (void *arg)
88 {
89 struct if_rmap *ifarg = arg;
90 struct if_rmap *if_rmap;
91
92 if_rmap = if_rmap_new ();
93 if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname);
94
95 return if_rmap;
96 }
97
98 static struct if_rmap *
99 if_rmap_get (const char *ifname)
100 {
101 struct if_rmap key;
102
103 /* temporary copy */
104 key.ifname = (char *)ifname;
105
106 return (struct if_rmap *) hash_get (ifrmaphash, &key, if_rmap_hash_alloc);
107 }
108
109 static unsigned int
110 if_rmap_hash_make (void *data)
111 {
112 const struct if_rmap *if_rmap = data;
113
114 return string_hash_make (if_rmap->ifname);
115 }
116
117 static int
118 if_rmap_hash_cmp (const void *arg1, const void* arg2)
119 {
120 const struct if_rmap *if_rmap1 = arg1;
121 const struct if_rmap *if_rmap2 = arg2;
122
123 return strcmp (if_rmap1->ifname, if_rmap2->ifname) == 0;
124 }
125 \f
126 static struct if_rmap *
127 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 if_rmap = if_rmap_get (ifname);
133
134 if (type == IF_RMAP_IN)
135 {
136 if (if_rmap->routemap[IF_RMAP_IN])
137 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
138 if_rmap->routemap[IF_RMAP_IN]
139 = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name);
140 }
141 if (type == IF_RMAP_OUT)
142 {
143 if (if_rmap->routemap[IF_RMAP_OUT])
144 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
145 if_rmap->routemap[IF_RMAP_OUT]
146 = XSTRDUP (MTYPE_IF_RMAP_NAME, 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 static 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 XFREE (MTYPE_IF_RMAP_NAME, 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 XFREE (MTYPE_IF_RMAP_NAME, 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
211 if (strncmp (argv[1], "i", 1) == 0)
212 type = IF_RMAP_IN;
213 else if (strncmp (argv[1], "o", 1) == 0)
214 type = IF_RMAP_OUT;
215 else
216 {
217 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
218 return CMD_WARNING;
219 }
220
221 if_rmap_set (argv[2], type, argv[0]);
222
223 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 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 if (strncmp (argv[1], "i", 1) == 0)
249 type = IF_RMAP_IN;
250 else if (strncmp (argv[1], "o", 1) == 0)
251 type = IF_RMAP_OUT;
252 else
253 {
254 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
255 return CMD_WARNING;
256 }
257
258 ret = if_rmap_unset (argv[2], type, argv[0]);
259 if (! ret)
260 {
261 vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE);
262 return CMD_WARNING;
263 }
264 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 \f
277 /* Configuration write function. */
278 int
279 config_write_if_rmap (struct vty *vty)
280 {
281 unsigned int i;
282 struct hash_backet *mp;
283 int write = 0;
284
285 for (i = 0; i < ifrmaphash->size; i++)
286 for (mp = ifrmaphash->index[i]; mp; mp = mp->next)
287 {
288 struct if_rmap *if_rmap;
289
290 if_rmap = mp->data;
291
292 if (if_rmap->routemap[IF_RMAP_IN])
293 {
294 vty_out (vty, " route-map %s in %s%s",
295 if_rmap->routemap[IF_RMAP_IN],
296 if_rmap->ifname,
297 VTY_NEWLINE);
298 write++;
299 }
300
301 if (if_rmap->routemap[IF_RMAP_OUT])
302 {
303 vty_out (vty, " route-map %s out %s%s",
304 if_rmap->routemap[IF_RMAP_OUT],
305 if_rmap->ifname,
306 VTY_NEWLINE);
307 write++;
308 }
309 }
310 return write;
311 }
312
313 void
314 if_rmap_reset ()
315 {
316 hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free);
317 }
318
319 void
320 if_rmap_init (int node)
321 {
322 ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
323 if (node == RIPNG_NODE) {
324 install_element (RIPNG_NODE, &if_ipv6_rmap_cmd);
325 install_element (RIPNG_NODE, &no_if_ipv6_rmap_cmd);
326 } else if (node == RIP_NODE) {
327 install_element (RIP_NODE, &if_rmap_cmd);
328 install_element (RIP_NODE, &no_if_rmap_cmd);
329 }
330 }