1/* 2 * OSPFv3 Route-Map 3 * Copyright (C) 1999 Yasuhiro Ohara 4 * 5 * This file is part of GNU Zebra. 6 * 7 * GNU Zebra is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2, or (at your option) any 10 * later version. 11 * 12 * GNU Zebra is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with GNU Zebra; see the file COPYING. If not, write to the 19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 * Boston, MA 02111-1307, USA. 21 */ 22 23#include <zebra.h> 24 25#if 1 26#include "ospf6d.h" 27#else 28#include "log.h" 29#include "memory.h" 30#include "linklist.h" 31#include "prefix.h" 32#include "command.h" 33#include "vty.h" 34#include "routemap.h" 35#include "plist.h" 36 37#include "ospf6_top.h" 38#include "ospf6_redistribute.h" 39#endif 40 41route_map_result_t 42ospf6_routemap_rule_match_address_prefixlist (void *rule, 43 struct prefix *prefix, 44 route_map_object_t type, 45 void *object) 46{ 47 struct prefix_list *plist; 48 49 if (type != RMAP_OSPF6) 50 return RMAP_NOMATCH; 51 52 plist = prefix_list_lookup (AFI_IP6, (char *) rule); 53 54 if (plist == NULL) 55 return RMAP_NOMATCH; 56 57 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? 58 RMAP_NOMATCH : RMAP_MATCH); 59} 60 61void * 62ospf6_routemap_rule_match_address_prefixlist_compile (char *arg) 63{ 64 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); 65} 66 67void 68ospf6_routemap_rule_match_address_prefixlist_free (void *rule) 69{ 70 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 71} 72 73struct route_map_rule_cmd ospf6_routemap_rule_match_address_prefixlist_cmd = 74{ 75 "ipv6 address prefix-list", 76 ospf6_routemap_rule_match_address_prefixlist, 77 ospf6_routemap_rule_match_address_prefixlist_compile, 78 ospf6_routemap_rule_match_address_prefixlist_free, 79}; 80 81route_map_result_t 82ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix, 83 route_map_object_t type, void *object) 84{ 85 char *metric_type = rule; 86 struct ospf6_route_req *route = object; 87 88 if (type != RMAP_OSPF6) 89 return RMAP_OKAY; 90 91 if (strcmp (metric_type, "type-2") == 0) 92 route->path.metric_type = 2; 93 else 94 route->path.metric_type = 1; 95 96 return RMAP_OKAY; 97} 98 99void * 100ospf6_routemap_rule_set_metric_type_compile (char *arg) 101{ 102 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); 103} 104 105void 106ospf6_routemap_rule_set_metric_type_free (void *rule) 107{ 108 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 109} 110 111struct route_map_rule_cmd ospf6_routemap_rule_set_metric_type_cmd = 112{ 113 "metric-type", 114 ospf6_routemap_rule_set_metric_type, 115 ospf6_routemap_rule_set_metric_type_compile, 116 ospf6_routemap_rule_set_metric_type_free, 117}; 118 119route_map_result_t 120ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix, 121 route_map_object_t type, void *object) 122{ 123 char *metric = rule; 124 struct ospf6_route_req *route = object; 125 126 if (type != RMAP_OSPF6) 127 return RMAP_OKAY; 128 129 route->path.cost = atoi (metric); 130 route->path.cost_e2 = atoi (metric); 131 132 return RMAP_OKAY; 133} 134 135void * 136ospf6_routemap_rule_set_metric_compile (char *arg) 137{ 138 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); 139} 140 141void 142ospf6_routemap_rule_set_metric_free (void *rule) 143{ 144 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 145} 146 147struct route_map_rule_cmd ospf6_routemap_rule_set_metric_cmd = 148{ 149 "metric", 150 ospf6_routemap_rule_set_metric, 151 ospf6_routemap_rule_set_metric_compile, 152 ospf6_routemap_rule_set_metric_free, 153}; 154 155route_map_result_t 156ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix, 157 route_map_object_t type, void *object) 158{ 159 char *forwarding = rule; 160 struct ospf6_route_req *route = object; 161 162 if (type != RMAP_OSPF6) 163 return RMAP_OKAY; 164 165 if (inet_pton (AF_INET6, forwarding, &route->nexthop.address) != 1) 166 { 167 memset (&route->nexthop.address, 0, sizeof (struct in6_addr)); 168 return RMAP_ERROR; 169 } 170 171 return RMAP_OKAY; 172} 173 174void * 175ospf6_routemap_rule_set_forwarding_compile (char *arg) 176{ 177 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); 178} 179 180void 181ospf6_routemap_rule_set_forwarding_free (void *rule) 182{ 183 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); 184} 185 186struct route_map_rule_cmd ospf6_routemap_rule_set_forwarding_cmd = 187{ 188 "forwarding-address", 189 ospf6_routemap_rule_set_forwarding, 190 ospf6_routemap_rule_set_forwarding_compile, 191 ospf6_routemap_rule_set_forwarding_free, 192}; 193 194int 195route_map_command_status (struct vty *vty, int ret) 196{ 197 if (! ret) 198 return CMD_SUCCESS; 199 200 switch (ret) 201 { 202 case RMAP_RULE_MISSING: 203 vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); 204 break; 205 case RMAP_COMPILE_ERROR: 206 vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); 207 break; 208 default: 209 vty_out (vty, "route-map add set failed.%s", VTY_NEWLINE); 210 break; 211 } 212 return CMD_WARNING; 213} 214 215/* add "match address" */ 216DEFUN (ospf6_routemap_match_address_prefixlist, 217 ospf6_routemap_match_address_prefixlist_cmd, 218 "match ipv6 address prefix-list WORD", 219 "Match values\n" 220 IPV6_STR 221 "Match address of route\n" 222 "Match entries of prefix-lists\n" 223 "IPv6 prefix-list name\n") 224{ 225 int ret = route_map_add_match ((struct route_map_index *) vty->index, 226 "ipv6 address prefix-list", argv[0]); 227 return route_map_command_status (vty, ret); 228} 229 230/* delete "match address" */ 231DEFUN (ospf6_routemap_no_match_address_prefixlist, 232 ospf6_routemap_no_match_address_prefixlist_cmd, 233 "no match ipv6 address prefix-list WORD", 234 NO_STR 235 "Match values\n" 236 IPV6_STR 237 "Match address of route\n" 238 "Match entries of prefix-lists\n" 239 "IPv6 prefix-list name\n") 240{ 241 int ret = route_map_delete_match ((struct route_map_index *) vty->index, 242 "ipv6 address prefix-list", argv[0]); 243 return route_map_command_status (vty, ret); 244} 245 246/* add "set metric-type" */ 247DEFUN (ospf6_routemap_set_metric_type, 248 ospf6_routemap_set_metric_type_cmd, 249 "set metric-type (type-1|type-2)", 250 "Set value\n" 251 "Type of metric\n" 252 "OSPF6 external type 1 metric\n" 253 "OSPF6 external type 2 metric\n") 254{ 255 int ret = route_map_add_set ((struct route_map_index *) vty->index, 256 "metric-type", argv[0]); 257 return route_map_command_status (vty, ret); 258} 259 260/* delete "set metric-type" */ 261DEFUN (ospf6_routemap_no_set_metric_type, 262 ospf6_routemap_no_set_metric_type_cmd, 263 "no set metric-type (type-1|type-2)", 264 NO_STR 265 "Set value\n" 266 "Type of metric\n" 267 "OSPF6 external type 1 metric\n" 268 "OSPF6 external type 2 metric\n") 269{ 270 int ret = route_map_delete_set ((struct route_map_index *) vty->index, 271 "metric-type", argv[0]); 272 return route_map_command_status (vty, ret); 273} 274 275/* add "set metric" */ 276DEFUN (set_metric, 277 set_metric_cmd, 278 "set metric <0-4294967295>", 279 "Set value\n" 280 "Metric value\n" 281 "Metric value\n") 282{ 283 int ret = route_map_add_set ((struct route_map_index *) vty->index, 284 "metric", argv[0]); 285 return route_map_command_status (vty, ret); 286} 287 288/* delete "set metric" */ 289DEFUN (no_set_metric, 290 no_set_metric_cmd, 291 "no set metric <0-4294967295>", 292 NO_STR 293 "Set value\n" 294 "Metric\n" 295 "METRIC value\n") 296{ 297 int ret = route_map_delete_set ((struct route_map_index *) vty->index, 298 "metric", argv[0]); 299 return route_map_command_status (vty, ret); 300} 301 302/* add "set forwarding-address" */ 303DEFUN (ospf6_routemap_set_forwarding, 304 ospf6_routemap_set_forwarding_cmd, 305 "set forwarding-address X:X::X:X", 306 "Set value\n" 307 "Forwarding Address\n" 308 "IPv6 Address\n") 309{ 310 int ret = route_map_add_set ((struct route_map_index *) vty->index, 311 "forwarding-address", argv[0]); 312 return route_map_command_status (vty, ret); 313} 314 315/* delete "set forwarding-address" */ 316DEFUN (ospf6_routemap_no_set_forwarding, 317 ospf6_routemap_no_set_forwarding_cmd, 318 "no set forwarding-address X:X::X:X", 319 NO_STR 320 "Set value\n" 321 "Forwarding Address\n" 322 "IPv6 Address\n") 323{ 324 int ret = route_map_delete_set ((struct route_map_index *) vty->index, 325 "forwarding-address", argv[0]); 326 return route_map_command_status (vty, ret); 327} 328 329void 330ospf6_routemap_init () 331{ 332 route_map_init (); 333 route_map_init_vty (); 334 route_map_add_hook (ospf6_redistribute_routemap_update); 335 route_map_delete_hook (ospf6_redistribute_routemap_update); 336 337 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd); 338 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd); 339 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd); 340 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd); 341 342 /* Match address prefix-list */ 343 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd); 344 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd); 345 346 /* ASE Metric Type (e.g. Type-1/Type-2) */ 347 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd); 348 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd); 349 350 /* ASE Metric */ 351 install_element (RMAP_NODE, &set_metric_cmd); 352 install_element (RMAP_NODE, &no_set_metric_cmd); 353 354 /* ASE Metric */ 355 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd); 356 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd); 357} 358 359