1/* RIPng routemap. 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 "if.h" 25#include "memory.h" 26#include "prefix.h" 27#include "routemap.h" 28#include "command.h" 29 30#include "ripngd/ripngd.h" 31 32#if 0 33/* `match interface IFNAME' */ 34route_map_result_t 35route_match_interface (void *rule, struct prefix *prefix, 36 route_map_object_t type, void *object) 37{ 38 struct ripng_info *rinfo; 39 struct interface *ifp; 40 char *ifname; 41 42 if (type == ROUTE_MAP_RIPNG) 43 { 44 ifname = rule; 45 ifp = if_lookup_by_name(ifname); 46 47 if (!ifp) 48 return RM_NOMATCH; 49 50 rinfo = object; 51 52 if (rinfo->ifindex == ifp->ifindex) 53 return RM_MATCH; 54 else 55 return RM_NOMATCH; 56 } 57 return RM_NOMATCH; 58} 59 60void * 61route_match_interface_compile (char *arg) 62{ 63 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); 64} 65 66void 67route_match_interface_free (void *rule) 68{ 69 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 70} 71 72struct route_map_rule_cmd route_match_interface_cmd = 73{ 74 "interface", 75 route_match_interface, 76 route_match_interface_compile, 77 route_match_interface_free 78}; 79#endif /* 0 */ 80 81struct rip_metric_modifier 82{ 83 enum 84 { 85 metric_increment, 86 metric_decrement, 87 metric_absolute 88 } type; 89 90 u_char metric; 91}; 92 93route_map_result_t 94route_set_metric (void *rule, struct prefix *prefix, 95 route_map_object_t type, void *object) 96{ 97 if (type == RMAP_RIPNG) 98 { 99 struct rip_metric_modifier *mod; 100 struct ripng_info *rinfo; 101 102 mod = rule; 103 rinfo = object; 104 105 if (mod->type == metric_increment) 106 rinfo->metric += mod->metric; 107 else if (mod->type == metric_decrement) 108 rinfo->metric -= mod->metric; 109 else if (mod->type == metric_absolute) 110 rinfo->metric = mod->metric; 111 112 if (rinfo->metric < 1) 113 rinfo->metric = 1; 114 if (rinfo->metric > RIPNG_METRIC_INFINITY) 115 rinfo->metric = RIPNG_METRIC_INFINITY; 116 117 rinfo->metric_set = 1; 118 } 119 return RMAP_OKAY; 120} 121 122void * 123route_set_metric_compile (char *arg) 124{ 125 int len; 126 char *pnt; 127 int type; 128 long metric; 129 char *endptr = NULL; 130 struct rip_metric_modifier *mod; 131 132 len = strlen (arg); 133 pnt = arg; 134 135 if (len == 0) 136 return NULL; 137 138 /* Examine first character. */ 139 if (arg[0] == '+') 140 { 141 type = metric_increment; 142 pnt++; 143 } 144 else if (arg[0] == '-') 145 { 146 type = metric_decrement; 147 pnt++; 148 } 149 else 150 type = metric_absolute; 151 152 /* Check beginning with digit string. */ 153 if (*pnt < '0' || *pnt > '9') 154 return NULL; 155 156 /* Convert string to integer. */ 157 metric = strtol (pnt, &endptr, 10); 158 159 if (metric == LONG_MAX || *endptr != '\0') 160 return NULL; 161 if (metric < 0 || metric > RIPNG_METRIC_INFINITY) 162 return NULL; 163 164 mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, 165 sizeof (struct rip_metric_modifier)); 166 mod->type = type; 167 mod->metric = metric; 168 169 return mod; 170} 171 172void 173route_set_metric_free (void *rule) 174{ 175 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 176} 177 178struct route_map_rule_cmd route_set_metric_cmd = 179{ 180 "metric", 181 route_set_metric, 182 route_set_metric_compile, 183 route_set_metric_free, 184}; 185 186int 187ripng_route_match_add (struct vty *vty, struct route_map_index *index, 188 char *command, char *arg) 189{ 190 int ret; 191 192 ret = route_map_add_match (index, command, arg); 193 if (ret) 194 { 195 switch (ret) 196 { 197 case RMAP_RULE_MISSING: 198 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); 199 return CMD_WARNING; 200 break; 201 case RMAP_COMPILE_ERROR: 202 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); 203 return CMD_WARNING; 204 break; 205 } 206 } 207 return CMD_SUCCESS; 208} 209 210int 211ripng_route_match_delete (struct vty *vty, struct route_map_index *index, 212 char *command, char *arg) 213{ 214 int ret; 215 216 ret = route_map_delete_match (index, command, arg); 217 if (ret) 218 { 219 switch (ret) 220 { 221 case RMAP_RULE_MISSING: 222 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); 223 return CMD_WARNING; 224 break; 225 case RMAP_COMPILE_ERROR: 226 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); 227 return CMD_WARNING; 228 break; 229 } 230 } 231 return CMD_SUCCESS; 232} 233 234int 235ripng_route_set_add (struct vty *vty, struct route_map_index *index, 236 char *command, char *arg) 237{ 238 int ret; 239 240 ret = route_map_add_set (index, command, arg); 241 if (ret) 242 { 243 switch (ret) 244 { 245 case RMAP_RULE_MISSING: 246 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); 247 return CMD_WARNING; 248 break; 249 case RMAP_COMPILE_ERROR: 250 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); 251 return CMD_WARNING; 252 break; 253 } 254 } 255 return CMD_SUCCESS; 256} 257 258int 259ripng_route_set_delete (struct vty *vty, struct route_map_index *index, 260 char *command, char *arg) 261{ 262 int ret; 263 264 ret = route_map_delete_set (index, command, arg); 265 if (ret) 266 { 267 switch (ret) 268 { 269 case RMAP_RULE_MISSING: 270 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); 271 return CMD_WARNING; 272 break; 273 case RMAP_COMPILE_ERROR: 274 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); 275 return CMD_WARNING; 276 break; 277 } 278 } 279 return CMD_SUCCESS; 280} 281 282#if 0 283DEFUN (match_interface, 284 match_interface_cmd, 285 "match interface WORD", 286 "Match value\n" 287 "Interface\n" 288 "Interface name\n") 289{ 290 return ripng_route_match_add (vty, vty->index, "interface", argv[0]); 291} 292 293DEFUN (no_match_interface, 294 no_match_interface_cmd, 295 "no match interface WORD", 296 NO_STR 297 "Match value\n" 298 "Interface\n" 299 "Interface name\n") 300{ 301 return ripng_route_match_delete (vty, vty->index, "interface", argv[0]); 302} 303#endif /* 0 */ 304 305DEFUN (set_metric, 306 set_metric_cmd, 307 "set metric <0-4294967295>", 308 "Set value\n" 309 "Metric\n" 310 "METRIC value\n") 311{ 312 return ripng_route_set_add (vty, vty->index, "metric", argv[0]); 313} 314 315DEFUN (no_set_metric, 316 no_set_metric_cmd, 317 "no set metric <0-4294967295>", 318 NO_STR 319 "Set value\n" 320 "Metric\n" 321 "METRIC value\n") 322{ 323 return ripng_route_set_delete (vty, vty->index, "metric", argv[0]); 324} 325 326void 327ripng_route_map_init () 328{ 329 route_map_init (); 330 route_map_init_vty (); 331 332 /* route_map_install_match (&route_match_interface_cmd); */ 333 route_map_install_set (&route_set_metric_cmd); 334 335 /* 336 install_element (RMAP_NODE, &match_interface_cmd); 337 install_element (RMAP_NODE, &no_match_interface_cmd); 338 */ 339 340 install_element (RMAP_NODE, &set_metric_cmd); 341 install_element (RMAP_NODE, &no_set_metric_cmd); 342} 343