]> git.proxmox.com Git - mirror_frr.git/blob - lib/if_rmap.c
mpls: add support for LDP LSPs
[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 DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map")
31 DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name")
32
33 struct hash *ifrmaphash;
34
35 /* Hook functions. */
36 static void (*if_rmap_add_hook) (struct if_rmap *) = NULL;
37 static void (*if_rmap_delete_hook) (struct if_rmap *) = NULL;
38
39 static struct if_rmap *
40 if_rmap_new (void)
41 {
42 struct if_rmap *new;
43
44 new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap));
45
46 return new;
47 }
48
49 static void
50 if_rmap_free (struct if_rmap *if_rmap)
51 {
52 if (if_rmap->ifname)
53 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->ifname);
54
55 if (if_rmap->routemap[IF_RMAP_IN])
56 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
57 if (if_rmap->routemap[IF_RMAP_OUT])
58 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
59
60 XFREE (MTYPE_IF_RMAP, if_rmap);
61 }
62
63 struct if_rmap *
64 if_rmap_lookup (const char *ifname)
65 {
66 struct if_rmap key;
67 struct if_rmap *if_rmap;
68
69 /* temporary copy */
70 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
71
72 if_rmap = hash_lookup (ifrmaphash, &key);
73
74 if (key.ifname)
75 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
76
77 return if_rmap;
78 }
79
80 void
81 if_rmap_hook_add (void (*func) (struct if_rmap *))
82 {
83 if_rmap_add_hook = func;
84 }
85
86 void
87 if_rmap_hook_delete (void (*func) (struct if_rmap *))
88 {
89 if_rmap_delete_hook = func;
90 }
91
92 static void *
93 if_rmap_hash_alloc (void *arg)
94 {
95 struct if_rmap *ifarg = (struct if_rmap *)arg;
96 struct if_rmap *if_rmap;
97
98 if_rmap = if_rmap_new ();
99 if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname);
100
101 return if_rmap;
102 }
103
104 static struct if_rmap *
105 if_rmap_get (const char *ifname)
106 {
107 struct if_rmap key;
108 struct if_rmap *ret;
109
110 /* temporary copy */
111 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
112
113 ret = hash_get (ifrmaphash, &key, if_rmap_hash_alloc);
114
115 if (key.ifname)
116 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
117
118 return ret;
119 }
120
121 static unsigned int
122 if_rmap_hash_make (void *data)
123 {
124 const struct if_rmap *if_rmap = data;
125
126 return string_hash_make (if_rmap->ifname);
127 }
128
129 static int
130 if_rmap_hash_cmp (const void *arg1, const void* arg2)
131 {
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;
136 }
137
138 static struct if_rmap *
139 if_rmap_set (const char *ifname, enum if_rmap_type type,
140 const char *routemap_name)
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])
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);
152 }
153 if (type == IF_RMAP_OUT)
154 {
155 if (if_rmap->routemap[IF_RMAP_OUT])
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);
159 }
160
161 if (if_rmap_add_hook)
162 (*if_rmap_add_hook) (if_rmap);
163
164 return if_rmap;
165 }
166
167 static int
168 if_rmap_unset (const char *ifname, enum if_rmap_type type,
169 const char *routemap_name)
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
184 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
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
195 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
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
212 DEFUN (if_rmap,
213 if_rmap_cmd,
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;
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
233 if_rmap_set (argv[2], type, argv[0]);
234
235 return CMD_SUCCESS;
236 }
237
238 ALIAS (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")
246
247 DEFUN (no_if_rmap,
248 no_if_rmap_cmd,
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;
277 }
278
279 ALIAS (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")
288
289 /* Configuration write function. */
290 int
291 config_write_if_rmap (struct vty *vty)
292 {
293 unsigned int i;
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
325 void
326 if_rmap_reset ()
327 {
328 hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free);
329 }
330
331 void
332 if_rmap_init (int node)
333 {
334 ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
335 if (node == RIPNG_NODE) {
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);
341 }
342 }