]>
Commit | Line | Data |
---|---|---|
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 | * | |
896014f4 DL |
16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
718e3744 | 19 | */ |
20 | ||
21 | #include <zebra.h> | |
22 | ||
23 | #include "hash.h" | |
24 | #include "command.h" | |
25 | #include "memory.h" | |
26 | #include "if.h" | |
0750d21f | 27 | #include "if_rmap.h" |
718e3744 | 28 | |
4a1ab8e4 DL |
29 | DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map") |
30 | DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name") | |
31 | ||
718e3744 | 32 | struct hash *ifrmaphash; |
33 | ||
34 | /* Hook functions. */ | |
8cc4198f | 35 | static void (*if_rmap_add_hook) (struct if_rmap *) = NULL; |
36 | static void (*if_rmap_delete_hook) (struct if_rmap *) = NULL; | |
6b0655a2 | 37 | |
8cc4198f | 38 | static struct if_rmap * |
39 | if_rmap_new (void) | |
718e3744 | 40 | { |
41 | struct if_rmap *new; | |
42 | ||
43 | new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap)); | |
44 | ||
45 | return new; | |
46 | } | |
47 | ||
8cc4198f | 48 | static void |
718e3744 | 49 | if_rmap_free (struct if_rmap *if_rmap) |
50 | { | |
51 | if (if_rmap->ifname) | |
0241684e | 52 | XFREE (MTYPE_IF_RMAP_NAME, if_rmap->ifname); |
718e3744 | 53 | |
54 | if (if_rmap->routemap[IF_RMAP_IN]) | |
0241684e | 55 | XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]); |
718e3744 | 56 | if (if_rmap->routemap[IF_RMAP_OUT]) |
0241684e | 57 | XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]); |
718e3744 | 58 | |
59 | XFREE (MTYPE_IF_RMAP, if_rmap); | |
60 | } | |
61 | ||
62 | struct if_rmap * | |
9035efaa | 63 | if_rmap_lookup (const char *ifname) |
718e3744 | 64 | { |
65 | struct if_rmap key; | |
66 | struct if_rmap *if_rmap; | |
67 | ||
9035efaa | 68 | /* temporary copy */ |
3a7c85d1 | 69 | key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL; |
718e3744 | 70 | |
71 | if_rmap = hash_lookup (ifrmaphash, &key); | |
72 | ||
3a7c85d1 DS |
73 | if (key.ifname) |
74 | XFREE(MTYPE_IF_RMAP_NAME, key.ifname); | |
75 | ||
718e3744 | 76 | return if_rmap; |
77 | } | |
78 | ||
79 | void | |
80 | if_rmap_hook_add (void (*func) (struct if_rmap *)) | |
81 | { | |
82 | if_rmap_add_hook = func; | |
83 | } | |
84 | ||
85 | void | |
86 | if_rmap_hook_delete (void (*func) (struct if_rmap *)) | |
87 | { | |
88 | if_rmap_delete_hook = func; | |
89 | } | |
90 | ||
8cc4198f | 91 | static void * |
92 | if_rmap_hash_alloc (void *arg) | |
718e3744 | 93 | { |
24873f0c | 94 | struct if_rmap *ifarg = (struct if_rmap *)arg; |
718e3744 | 95 | struct if_rmap *if_rmap; |
96 | ||
97 | if_rmap = if_rmap_new (); | |
0241684e | 98 | if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname); |
718e3744 | 99 | |
100 | return if_rmap; | |
101 | } | |
102 | ||
8cc4198f | 103 | static struct if_rmap * |
9035efaa | 104 | if_rmap_get (const char *ifname) |
718e3744 | 105 | { |
106 | struct if_rmap key; | |
24873f0c | 107 | struct if_rmap *ret; |
718e3744 | 108 | |
9035efaa | 109 | /* temporary copy */ |
3a7c85d1 | 110 | key.ifname = (ifname) ? XSTRDUP (MTYPE_IF_RMAP_NAME, ifname) : NULL; |
718e3744 | 111 | |
24873f0c | 112 | ret = hash_get (ifrmaphash, &key, if_rmap_hash_alloc); |
3a7c85d1 | 113 | |
24873f0c DS |
114 | if (key.ifname) |
115 | XFREE(MTYPE_IF_RMAP_NAME, key.ifname); | |
116 | ||
117 | return ret; | |
718e3744 | 118 | } |
119 | ||
8cc4198f | 120 | static unsigned int |
121 | if_rmap_hash_make (void *data) | |
718e3744 | 122 | { |
6392aa83 | 123 | const struct if_rmap *if_rmap = data; |
718e3744 | 124 | |
6392aa83 | 125 | return string_hash_make (if_rmap->ifname); |
718e3744 | 126 | } |
127 | ||
8cc4198f | 128 | static int |
ffe11cfb | 129 | if_rmap_hash_cmp (const void *arg1, const void* arg2) |
718e3744 | 130 | { |
ffe11cfb SH |
131 | const struct if_rmap *if_rmap1 = arg1; |
132 | const struct if_rmap *if_rmap2 = arg2; | |
133 | ||
134 | return strcmp (if_rmap1->ifname, if_rmap2->ifname) == 0; | |
718e3744 | 135 | } |
6b0655a2 | 136 | |
8cc4198f | 137 | static struct if_rmap * |
9035efaa | 138 | if_rmap_set (const char *ifname, enum if_rmap_type type, |
139 | const char *routemap_name) | |
718e3744 | 140 | { |
141 | struct if_rmap *if_rmap; | |
142 | ||
143 | if_rmap = if_rmap_get (ifname); | |
144 | ||
145 | if (type == IF_RMAP_IN) | |
146 | { | |
147 | if (if_rmap->routemap[IF_RMAP_IN]) | |
0241684e | 148 | XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]); |
149 | if_rmap->routemap[IF_RMAP_IN] | |
150 | = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name); | |
718e3744 | 151 | } |
152 | if (type == IF_RMAP_OUT) | |
153 | { | |
154 | if (if_rmap->routemap[IF_RMAP_OUT]) | |
0241684e | 155 | XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]); |
156 | if_rmap->routemap[IF_RMAP_OUT] | |
157 | = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name); | |
718e3744 | 158 | } |
159 | ||
160 | if (if_rmap_add_hook) | |
161 | (*if_rmap_add_hook) (if_rmap); | |
162 | ||
163 | return if_rmap; | |
164 | } | |
165 | ||
8cc4198f | 166 | static int |
9035efaa | 167 | if_rmap_unset (const char *ifname, enum if_rmap_type type, |
168 | const char *routemap_name) | |
718e3744 | 169 | { |
170 | struct if_rmap *if_rmap; | |
171 | ||
172 | if_rmap = if_rmap_lookup (ifname); | |
173 | if (!if_rmap) | |
174 | return 0; | |
175 | ||
176 | if (type == IF_RMAP_IN) | |
177 | { | |
178 | if (!if_rmap->routemap[IF_RMAP_IN]) | |
179 | return 0; | |
180 | if (strcmp (if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0) | |
181 | return 0; | |
182 | ||
0241684e | 183 | XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]); |
718e3744 | 184 | if_rmap->routemap[IF_RMAP_IN] = NULL; |
185 | } | |
186 | ||
187 | if (type == IF_RMAP_OUT) | |
188 | { | |
189 | if (!if_rmap->routemap[IF_RMAP_OUT]) | |
190 | return 0; | |
191 | if (strcmp (if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0) | |
192 | return 0; | |
193 | ||
0241684e | 194 | XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]); |
718e3744 | 195 | if_rmap->routemap[IF_RMAP_OUT] = NULL; |
196 | } | |
197 | ||
198 | if (if_rmap_delete_hook) | |
199 | (*if_rmap_delete_hook) (if_rmap); | |
200 | ||
201 | if (if_rmap->routemap[IF_RMAP_IN] == NULL && | |
202 | if_rmap->routemap[IF_RMAP_OUT] == NULL) | |
203 | { | |
204 | hash_release (ifrmaphash, if_rmap); | |
205 | if_rmap_free (if_rmap); | |
206 | } | |
207 | ||
208 | return 1; | |
209 | } | |
210 | ||
0750d21f | 211 | DEFUN (if_rmap, |
212 | if_rmap_cmd, | |
6147e2c6 | 213 | "route-map RMAP_NAME <in|out> IFNAME", |
718e3744 | 214 | "Route map set\n" |
215 | "Route map name\n" | |
216 | "Route map set for input filtering\n" | |
217 | "Route map set for output filtering\n" | |
218 | "Route map interface name\n") | |
219 | { | |
c349116d DW |
220 | int idx_rmap_name = 1; |
221 | int idx_in_out = 2; | |
222 | int idx_ifname = 3; | |
718e3744 | 223 | enum if_rmap_type type; |
718e3744 | 224 | |
d862bffb | 225 | if (strncmp (argv[idx_in_out]->text, "in", 1) == 0) |
718e3744 | 226 | type = IF_RMAP_IN; |
d862bffb | 227 | else if (strncmp (argv[idx_in_out]->text, "out", 1) == 0) |
718e3744 | 228 | type = IF_RMAP_OUT; |
229 | else | |
230 | { | |
5c7571d4 | 231 | vty_out (vty, "route-map direction must be [in|out]\n"); |
718e3744 | 232 | return CMD_WARNING; |
233 | } | |
234 | ||
c349116d | 235 | if_rmap_set (argv[idx_ifname]->arg, type, argv[idx_rmap_name]->arg); |
718e3744 | 236 | |
237 | return CMD_SUCCESS; | |
c349116d | 238 | } |
4f849479 | 239 | |
0750d21f | 240 | DEFUN (no_if_rmap, |
241 | no_if_rmap_cmd, | |
6147e2c6 | 242 | "no route-map ROUTEMAP_NAME <in|out> IFNAME", |
718e3744 | 243 | NO_STR |
244 | "Route map unset\n" | |
245 | "Route map name\n" | |
246 | "Route map for input filtering\n" | |
247 | "Route map for output filtering\n" | |
248 | "Route map interface name\n") | |
249 | { | |
c349116d DW |
250 | int idx_routemap_name = 2; |
251 | int idx_in_out = 3; | |
252 | int idx_ifname = 4; | |
718e3744 | 253 | int ret; |
254 | enum if_rmap_type type; | |
255 | ||
c349116d | 256 | if (strncmp (argv[idx_in_out]->arg, "i", 1) == 0) |
718e3744 | 257 | type = IF_RMAP_IN; |
c349116d | 258 | else if (strncmp (argv[idx_in_out]->arg, "o", 1) == 0) |
718e3744 | 259 | type = IF_RMAP_OUT; |
260 | else | |
261 | { | |
5c7571d4 | 262 | vty_out (vty, "route-map direction must be [in|out]\n"); |
718e3744 | 263 | return CMD_WARNING; |
264 | } | |
265 | ||
c349116d | 266 | ret = if_rmap_unset (argv[idx_ifname]->arg, type, argv[idx_routemap_name]->arg); |
718e3744 | 267 | if (! ret) |
268 | { | |
5c7571d4 | 269 | vty_out (vty, "route-map doesn't exist\n"); |
718e3744 | 270 | return CMD_WARNING; |
271 | } | |
272 | return CMD_SUCCESS; | |
c349116d | 273 | } |
4f849479 | 274 | |
6b0655a2 | 275 | |
718e3744 | 276 | /* Configuration write function. */ |
277 | int | |
278 | config_write_if_rmap (struct vty *vty) | |
279 | { | |
8c328f11 | 280 | unsigned int i; |
718e3744 | 281 | struct hash_backet *mp; |
282 | int write = 0; | |
283 | ||
284 | for (i = 0; i < ifrmaphash->size; i++) | |
285 | for (mp = ifrmaphash->index[i]; mp; mp = mp->next) | |
286 | { | |
287 | struct if_rmap *if_rmap; | |
288 | ||
289 | if_rmap = mp->data; | |
290 | ||
291 | if (if_rmap->routemap[IF_RMAP_IN]) | |
292 | { | |
5c7571d4 | 293 | vty_out (vty, " route-map %s in %s\n", |
718e3744 | 294 | if_rmap->routemap[IF_RMAP_IN], |
96ade3ed | 295 | if_rmap->ifname); |
718e3744 | 296 | write++; |
297 | } | |
298 | ||
299 | if (if_rmap->routemap[IF_RMAP_OUT]) | |
300 | { | |
5c7571d4 | 301 | vty_out (vty, " route-map %s out %s\n", |
718e3744 | 302 | if_rmap->routemap[IF_RMAP_OUT], |
96ade3ed | 303 | if_rmap->ifname); |
718e3744 | 304 | write++; |
305 | } | |
306 | } | |
307 | return write; | |
308 | } | |
309 | ||
310 | void | |
311 | if_rmap_reset () | |
312 | { | |
313 | hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free); | |
314 | } | |
315 | ||
316 | void | |
0750d21f | 317 | if_rmap_init (int node) |
718e3744 | 318 | { |
dfd19ccc | 319 | ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp, NULL); |
0750d21f | 320 | if (node == RIPNG_NODE) { |
4f849479 | 321 | } else if (node == RIP_NODE) { |
322 | install_element (RIP_NODE, &if_rmap_cmd); | |
323 | install_element (RIP_NODE, &no_if_rmap_cmd); | |
0750d21f | 324 | } |
718e3744 | 325 | } |