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#ifdef FOX_LIST_SUPPORT 23 24#include <zebra.h> 25 26#include "hash.h" 27#include "command.h" 28#include "memory.h" 29#include "if.h" 30#include "if_rmap.h" 31 32struct hash *ifrmaphash; 33 34/* Hook functions. */ 35void (*if_rmap_add_hook) (struct if_rmap *) = NULL; 36void (*if_rmap_delete_hook) (struct if_rmap *) = NULL; 37 38struct if_rmap * 39if_rmap_new () 40{ 41 struct if_rmap *new; 42 43 new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap)); 44 45 return new; 46} 47 48void 49if_rmap_free (struct if_rmap *if_rmap) 50{ 51 if (if_rmap->ifname) 52 free (if_rmap->ifname); 53 54 if (if_rmap->routemap[IF_RMAP_IN]) 55 free (if_rmap->routemap[IF_RMAP_IN]); 56 if (if_rmap->routemap[IF_RMAP_OUT]) 57 free (if_rmap->routemap[IF_RMAP_OUT]); 58 59 XFREE (MTYPE_IF_RMAP, if_rmap); 60} 61 62struct if_rmap * 63if_rmap_lookup (char *ifname) 64{ 65 struct if_rmap key; 66 struct if_rmap *if_rmap; 67 68 key.ifname = ifname; 69 70 if_rmap = hash_lookup (ifrmaphash, &key); 71 72 return if_rmap; 73} 74 75void 76if_rmap_hook_add (void (*func) (struct if_rmap *)) 77{ 78 if_rmap_add_hook = func; 79} 80 81void 82if_rmap_hook_delete (void (*func) (struct if_rmap *)) 83{ 84 if_rmap_delete_hook = func; 85} 86 87void * 88if_rmap_hash_alloc (struct if_rmap *arg) 89{ 90 struct if_rmap *if_rmap; 91 92 if_rmap = if_rmap_new (); 93 if_rmap->ifname = strdup (arg->ifname); 94 95 return if_rmap; 96} 97 98struct if_rmap * 99if_rmap_get (char *ifname) 100{ 101 struct if_rmap key; 102 103 key.ifname = ifname; 104 105 return (struct if_rmap *) hash_get (ifrmaphash, &key, if_rmap_hash_alloc); 106} 107 108unsigned int 109if_rmap_hash_make (struct if_rmap *if_rmap) 110{ 111 unsigned int key; 112 int i; 113 114 key = 0; 115 for (i = 0; i < strlen (if_rmap->ifname); i++) 116 key += if_rmap->ifname[i]; 117 118 return key; 119} 120 121int 122if_rmap_hash_cmp (struct if_rmap *if_rmap1, struct if_rmap *if_rmap2) 123{ 124 if (strcmp (if_rmap1->ifname, if_rmap2->ifname) == 0) 125 return 1; 126 return 0; 127} 128 129struct if_rmap * 130if_rmap_set (char *ifname, enum if_rmap_type type, char *routemap_name) 131{ 132 struct if_rmap *if_rmap; 133 134 if_rmap = if_rmap_get (ifname); 135 136 if (type == IF_RMAP_IN) 137 { 138 if (if_rmap->routemap[IF_RMAP_IN]) 139 free (if_rmap->routemap[IF_RMAP_IN]); 140 if_rmap->routemap[IF_RMAP_IN] = strdup (routemap_name); 141 } 142 if (type == IF_RMAP_OUT) 143 { 144 if (if_rmap->routemap[IF_RMAP_OUT]) 145 free (if_rmap->routemap[IF_RMAP_OUT]); 146 if_rmap->routemap[IF_RMAP_OUT] = strdup (routemap_name); 147 } 148 149 if (if_rmap_add_hook) 150 (*if_rmap_add_hook) (if_rmap); 151 152 return if_rmap; 153} 154 155int 156if_rmap_unset (char *ifname, enum if_rmap_type type, char *routemap_name) 157{ 158 struct if_rmap *if_rmap; 159 160 if_rmap = if_rmap_lookup (ifname); 161 if (!if_rmap) 162 return 0; 163 164 if (type == IF_RMAP_IN) 165 { 166 if (!if_rmap->routemap[IF_RMAP_IN]) 167 return 0; 168 if (strcmp (if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0) 169 return 0; 170 171 free (if_rmap->routemap[IF_RMAP_IN]); 172 if_rmap->routemap[IF_RMAP_IN] = NULL; 173 } 174 175 if (type == IF_RMAP_OUT) 176 { 177 if (!if_rmap->routemap[IF_RMAP_OUT]) 178 return 0; 179 if (strcmp (if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0) 180 return 0; 181 182 free (if_rmap->routemap[IF_RMAP_OUT]); 183 if_rmap->routemap[IF_RMAP_OUT] = NULL; 184 } 185 186 if (if_rmap_delete_hook) 187 (*if_rmap_delete_hook) (if_rmap); 188 189 if (if_rmap->routemap[IF_RMAP_IN] == NULL && 190 if_rmap->routemap[IF_RMAP_OUT] == NULL) 191 { 192 hash_release (ifrmaphash, if_rmap); 193 if_rmap_free (if_rmap); 194 } 195 196 return 1; 197} 198 199DEFUN (if_rmap, 200 if_rmap_cmd, 201 "route-map RMAP_NAME (in|out) IFNAME", 202 "Route map set\n" 203 "Route map name\n" 204 "Route map set for input filtering\n" 205 "Route map set for output filtering\n" 206 "Route map interface name\n") 207{ 208 enum if_rmap_type type; 209 struct if_rmap *if_rmap; 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 = if_rmap_set (argv[2], type, argv[0]); 222 223 return CMD_SUCCESS; 224} 225 226DEFUN (no_if_rmap, 227 no_if_rmap_cmd, 228 "no route-map ROUTEMAP_NAME (in|out) IFNAME", 229 NO_STR 230 "Route map unset\n" 231 "Route map name\n" 232 "Route map for input filtering\n" 233 "Route map for output filtering\n" 234 "Route map interface name\n") 235{ 236 int ret; 237 enum if_rmap_type type; 238 239 if (strncmp (argv[1], "i", 1) == 0) 240 type = IF_RMAP_IN; 241 else if (strncmp (argv[1], "o", 1) == 0) 242 type = IF_RMAP_OUT; 243 else 244 { 245 vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE); 246 return CMD_WARNING; 247 } 248 249 ret = if_rmap_unset (argv[2], type, argv[0]); 250 if (! ret) 251 { 252 vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE); 253 return CMD_WARNING; 254 } 255 return CMD_SUCCESS; 256} 257 258/* Configuration write function. */ 259int 260config_write_if_rmap (struct vty *vty) 261{ 262 int i; 263 struct hash_backet *mp; 264 int write = 0; 265 266 for (i = 0; i < ifrmaphash->size; i++) 267 for (mp = ifrmaphash->index[i]; mp; mp = mp->next) 268 { 269 struct if_rmap *if_rmap; 270 271 if_rmap = mp->data; 272 273 if (if_rmap->routemap[IF_RMAP_IN]) 274 { 275 vty_out (vty, " route-map %s in %s%s", 276 if_rmap->routemap[IF_RMAP_IN], 277 if_rmap->ifname, 278 VTY_NEWLINE); 279 write++; 280 } 281 282 if (if_rmap->routemap[IF_RMAP_OUT]) 283 { 284 vty_out (vty, " route-map %s out %s%s", 285 if_rmap->routemap[IF_RMAP_OUT], 286 if_rmap->ifname, 287 VTY_NEWLINE); 288 write++; 289 } 290 } 291 return write; 292} 293 294void 295if_rmap_reset () 296{ 297 hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free); 298} 299 300void 301if_rmap_init (int node) 302{ 303 ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp); 304 305 install_element (node, &if_rmap_cmd); 306 install_element (node, &no_if_rmap_cmd); 307} 308#endif /* FOX_LIST_SUPPORT */ 309