]> git.proxmox.com Git - mirror_frr.git/blame - lib/if_rmap.c
tools: argv_translator convert <1-255> to (1-255), ()s to <>s, etc
[mirror_frr.git] / lib / if_rmap.c
CommitLineData
718e3744 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"
0750d21f 28#include "if_rmap.h"
718e3744 29
4a1ab8e4
DL
30DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map")
31DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name")
32
718e3744 33struct hash *ifrmaphash;
34
35/* Hook functions. */
8cc4198f 36static void (*if_rmap_add_hook) (struct if_rmap *) = NULL;
37static void (*if_rmap_delete_hook) (struct if_rmap *) = NULL;
6b0655a2 38
8cc4198f 39static struct if_rmap *
40if_rmap_new (void)
718e3744 41{
42 struct if_rmap *new;
43
44 new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap));
45
46 return new;
47}
48
8cc4198f 49static void
718e3744 50if_rmap_free (struct if_rmap *if_rmap)
51{
52 if (if_rmap->ifname)
0241684e 53 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->ifname);
718e3744 54
55 if (if_rmap->routemap[IF_RMAP_IN])
0241684e 56 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
718e3744 57 if (if_rmap->routemap[IF_RMAP_OUT])
0241684e 58 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
718e3744 59
60 XFREE (MTYPE_IF_RMAP, if_rmap);
61}
62
63struct if_rmap *
9035efaa 64if_rmap_lookup (const char *ifname)
718e3744 65{
66 struct if_rmap key;
67 struct if_rmap *if_rmap;
68
9035efaa 69 /* temporary copy */
3a7c85d1 70 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
718e3744 71
72 if_rmap = hash_lookup (ifrmaphash, &key);
73
3a7c85d1
DS
74 if (key.ifname)
75 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
76
718e3744 77 return if_rmap;
78}
79
80void
81if_rmap_hook_add (void (*func) (struct if_rmap *))
82{
83 if_rmap_add_hook = func;
84}
85
86void
87if_rmap_hook_delete (void (*func) (struct if_rmap *))
88{
89 if_rmap_delete_hook = func;
90}
91
8cc4198f 92static void *
93if_rmap_hash_alloc (void *arg)
718e3744 94{
24873f0c 95 struct if_rmap *ifarg = (struct if_rmap *)arg;
718e3744 96 struct if_rmap *if_rmap;
97
98 if_rmap = if_rmap_new ();
0241684e 99 if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname);
718e3744 100
101 return if_rmap;
102}
103
8cc4198f 104static struct if_rmap *
9035efaa 105if_rmap_get (const char *ifname)
718e3744 106{
107 struct if_rmap key;
24873f0c 108 struct if_rmap *ret;
718e3744 109
9035efaa 110 /* temporary copy */
3a7c85d1 111 key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL;
718e3744 112
24873f0c 113 ret = hash_get (ifrmaphash, &key, if_rmap_hash_alloc);
3a7c85d1 114
24873f0c
DS
115 if (key.ifname)
116 XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
117
118 return ret;
718e3744 119}
120
8cc4198f 121static unsigned int
122if_rmap_hash_make (void *data)
718e3744 123{
6392aa83 124 const struct if_rmap *if_rmap = data;
718e3744 125
6392aa83 126 return string_hash_make (if_rmap->ifname);
718e3744 127}
128
8cc4198f 129static int
ffe11cfb 130if_rmap_hash_cmp (const void *arg1, const void* arg2)
718e3744 131{
ffe11cfb
SH
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;
718e3744 136}
6b0655a2 137
8cc4198f 138static struct if_rmap *
9035efaa 139if_rmap_set (const char *ifname, enum if_rmap_type type,
140 const char *routemap_name)
718e3744 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])
0241684e 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);
718e3744 152 }
153 if (type == IF_RMAP_OUT)
154 {
155 if (if_rmap->routemap[IF_RMAP_OUT])
0241684e 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);
718e3744 159 }
160
161 if (if_rmap_add_hook)
162 (*if_rmap_add_hook) (if_rmap);
163
164 return if_rmap;
165}
166
8cc4198f 167static int
9035efaa 168if_rmap_unset (const char *ifname, enum if_rmap_type type,
169 const char *routemap_name)
718e3744 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
0241684e 184 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
718e3744 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
0241684e 195 XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
718e3744 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
f412b39a
DW
212/*
213 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
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 */
0750d21f 222DEFUN (if_rmap,
223 if_rmap_cmd,
718e3744 224 "route-map RMAP_NAME (in|out) IFNAME",
225 "Route map set\n"
226 "Route map name\n"
227 "Route map set for input filtering\n"
228 "Route map set for output filtering\n"
229 "Route map interface name\n")
230{
231 enum if_rmap_type type;
718e3744 232
6f1ccc12 233 if (strncmp (argv[2]->arg, "i", 1) == 0)
718e3744 234 type = IF_RMAP_IN;
6f1ccc12 235 else if (strncmp (argv[2]->arg, "o", 1) == 0)
718e3744 236 type = IF_RMAP_OUT;
237 else
238 {
239 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
240 return CMD_WARNING;
241 }
242
6f1ccc12 243 if_rmap_set (argv[3]->arg, type, argv[1]->arg);
718e3744 244
245 return CMD_SUCCESS;
4f849479 246}
247
718e3744 248
f412b39a
DW
249/*
250 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
251 * "no route-map ROUTEMAP_NAME (in|out) IFNAME",
252 * NO_STR
253 * "Route map unset\n"
254 * "Route map name\n"
255 * "Route map for input filtering\n"
256 * "Route map for output filtering\n"
257 * "Route map interface name\n"
258 *
259 */
0750d21f 260DEFUN (no_if_rmap,
261 no_if_rmap_cmd,
718e3744 262 "no route-map ROUTEMAP_NAME (in|out) IFNAME",
263 NO_STR
264 "Route map unset\n"
265 "Route map name\n"
266 "Route map for input filtering\n"
267 "Route map for output filtering\n"
268 "Route map interface name\n")
269{
270 int ret;
271 enum if_rmap_type type;
272
6f1ccc12 273 if (strncmp (argv[3]->arg, "i", 1) == 0)
718e3744 274 type = IF_RMAP_IN;
6f1ccc12 275 else if (strncmp (argv[3]->arg, "o", 1) == 0)
718e3744 276 type = IF_RMAP_OUT;
277 else
278 {
279 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
280 return CMD_WARNING;
281 }
282
6f1ccc12 283 ret = if_rmap_unset (argv[4]->arg, type, argv[2]->arg);
718e3744 284 if (! ret)
285 {
286 vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE);
287 return CMD_WARNING;
288 }
289 return CMD_SUCCESS;
4f849479 290}
291
6b0655a2 292
718e3744 293/* Configuration write function. */
294int
295config_write_if_rmap (struct vty *vty)
296{
8c328f11 297 unsigned int i;
718e3744 298 struct hash_backet *mp;
299 int write = 0;
300
301 for (i = 0; i < ifrmaphash->size; i++)
302 for (mp = ifrmaphash->index[i]; mp; mp = mp->next)
303 {
304 struct if_rmap *if_rmap;
305
306 if_rmap = mp->data;
307
308 if (if_rmap->routemap[IF_RMAP_IN])
309 {
310 vty_out (vty, " route-map %s in %s%s",
311 if_rmap->routemap[IF_RMAP_IN],
312 if_rmap->ifname,
313 VTY_NEWLINE);
314 write++;
315 }
316
317 if (if_rmap->routemap[IF_RMAP_OUT])
318 {
319 vty_out (vty, " route-map %s out %s%s",
320 if_rmap->routemap[IF_RMAP_OUT],
321 if_rmap->ifname,
322 VTY_NEWLINE);
323 write++;
324 }
325 }
326 return write;
327}
328
329void
330if_rmap_reset ()
331{
332 hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free);
333}
334
335void
0750d21f 336if_rmap_init (int node)
718e3744 337{
338 ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
0750d21f 339 if (node == RIPNG_NODE) {
4f849479 340 } else if (node == RIP_NODE) {
341 install_element (RIP_NODE, &if_rmap_cmd);
342 install_element (RIP_NODE, &no_if_rmap_cmd);
0750d21f 343 }
718e3744 344}