diff options
Diffstat (limited to 'lib/routemap.c')
-rw-r--r-- | lib/routemap.c | 206 |
1 files changed, 113 insertions, 93 deletions
diff --git a/lib/routemap.c b/lib/routemap.c index 4f4e6d62..b452530d 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -28,7 +28,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "command.h" #include "vty.h" #include "log.h" - + /* Vector for route match rules. */ static vector route_match_vec; @@ -60,7 +60,7 @@ struct route_map_list void (*add_hook) (const char *); void (*delete_hook) (const char *); - void (*event_hook) (route_map_event_t, const char *); + void (*event_hook) (route_map_event_t, const char *); }; /* Master list of route map. */ @@ -72,7 +72,7 @@ route_map_rule_delete (struct route_map_rule_list *, static void route_map_index_delete (struct route_map_index *, int); - + /* New route map allocation. Please note route map's name must be specified. */ static struct route_map * @@ -94,7 +94,7 @@ route_map_add (const char *name) map = route_map_new (name); list = &route_map_master; - + map->next = NULL; map->prev = list->tail; if (list->tail) @@ -117,7 +117,7 @@ route_map_delete (struct route_map *map) struct route_map_list *list; struct route_map_index *index; char *name; - + while ((index = map->head) != NULL) route_map_index_delete (index, 0); @@ -207,44 +207,58 @@ vty_show_route_map_entry (struct vty *vty, struct route_map *map) /* Print the name of the protocol */ if (zlog_default) - vty_out (vty, "%s:%s", zlog_proto_names[zlog_default->protocol], + vty_out (vty, "%s:%s", zlog_get_proto_name(NULL), VTY_NEWLINE); for (index = map->head; index; index = index->next) { - vty_out (vty, "route-map %s, %s, sequence %d%s", + vty_out (vty, "route-map %s, %s, sequence %lu%s", map->name, route_map_type_str (index->type), - index->pref, VTY_NEWLINE); + (unsigned long)index->seq, VTY_NEWLINE); + confirm(sizeof(index->seq) <= sizeof(unsigned long)) ; /* Description */ if (index->description) vty_out (vty, " Description:%s %s%s", VTY_NEWLINE, index->description, VTY_NEWLINE); - + /* Match clauses */ vty_out (vty, " Match clauses:%s", VTY_NEWLINE); for (rule = index->match_list.head; rule; rule = rule->next) - vty_out (vty, " %s %s%s", + vty_out (vty, " %s %s%s", rule->cmd->str, rule->rule_str, VTY_NEWLINE); - + vty_out (vty, " Set clauses:%s", VTY_NEWLINE); for (rule = index->set_list.head; rule; rule = rule->next) vty_out (vty, " %s %s%s", rule->cmd->str, rule->rule_str, VTY_NEWLINE); - + /* Call clause */ vty_out (vty, " Call clause:%s", VTY_NEWLINE); if (index->nextrm) vty_out (vty, " Call %s%s", index->nextrm, VTY_NEWLINE); - + /* Exit Policy */ vty_out (vty, " Action:%s", VTY_NEWLINE); - if (index->exitpolicy == RMAP_GOTO) - vty_out (vty, " Goto %d%s", index->nextpref, VTY_NEWLINE); - else if (index->exitpolicy == RMAP_NEXT) - vty_out (vty, " Continue to next entry%s", VTY_NEWLINE); - else if (index->exitpolicy == RMAP_EXIT) - vty_out (vty, " Exit routemap%s", VTY_NEWLINE); + switch (index->exitpolicy) + { + case RMAP_GOTO: + vty_out (vty, " Goto %lu%s", (unsigned long)index->goto_seq, + VTY_NEWLINE); + confirm(sizeof(index->goto_seq) <= sizeof(unsigned long)) ; + break ; + + case RMAP_NEXT: + vty_out (vty, " Continue to next entry%s", VTY_NEWLINE); + break ; + + case RMAP_EXIT: + vty_out (vty, " Exit routemap%s", VTY_NEWLINE); + break ; + + default: + zabort("invalid route-map 'exitpolicy'") ; + } ; } } @@ -329,13 +343,12 @@ route_map_index_delete (struct route_map_index *index, int notify) /* Lookup index from route map. */ static struct route_map_index * route_map_index_lookup (struct route_map *map, enum route_map_type type, - int pref) + route_map_seq_t seq) { struct route_map_index *index; for (index = map->head; index; index = index->next) - if ((index->type == type || type == RMAP_ANY) - && index->pref == pref) + if ((index->type == type || type == RMAP_ANY) && index->seq == seq) return index; return NULL; } @@ -343,20 +356,20 @@ route_map_index_lookup (struct route_map *map, enum route_map_type type, /* Add new index to route map. */ static struct route_map_index * route_map_index_add (struct route_map *map, enum route_map_type type, - int pref) + route_map_seq_t seq) { struct route_map_index *index; struct route_map_index *point; - /* Allocate new route map inex. */ + /* Allocate new route map index. */ index = route_map_index_new (); - index->map = map; + index->map = map; index->type = type; - index->pref = pref; - - /* Compare preference. */ + index->seq = seq; + + /* Compare sequence number */ for (point = map->head; point; point = point->next) - if (point->pref >= pref) + if (point->seq >= seq) break; if (map->head == NULL) @@ -394,12 +407,12 @@ route_map_index_add (struct route_map *map, enum route_map_type type, /* Get route map index. */ static struct route_map_index * -route_map_index_get (struct route_map *map, enum route_map_type type, - int pref) +route_map_index_get (struct route_map *map, enum route_map_type type, + route_map_seq_t seq) { struct route_map_index *index; - index = route_map_index_lookup (map, RMAP_ANY, pref); + index = route_map_index_lookup (map, RMAP_ANY, seq); if (index && index->type != type) { /* Delete index from route map. */ @@ -407,7 +420,7 @@ route_map_index_get (struct route_map *map, enum route_map_type type, index = NULL; } if (index == NULL) - index = route_map_index_add (map, type, pref); + index = route_map_index_add (map, type, seq); return index; } @@ -420,7 +433,7 @@ route_map_rule_new (void) new = XCALLOC (MTYPE_ROUTE_MAP_RULE, sizeof (struct route_map_rule)); return new; } - + /* Install rule command to the match list. */ void route_map_install_match (struct route_map_rule_cmd *cmd) @@ -552,7 +565,7 @@ route_map_add_match (struct route_map_index *index, const char *match_name, { next = rule->next; if (rule->cmd == cmd) - { + { route_map_rule_delete (&index->match_list, rule); replaced = 1; } @@ -591,9 +604,9 @@ route_map_delete_match (struct route_map_index *index, const char *match_name, cmd = route_map_lookup_match (match_name); if (cmd == NULL) return 1; - + for (rule = index->match_list.head; rule; rule = rule->next) - if (rule->cmd == cmd && + if (rule->cmd == cmd && (rulecmp (rule->rule_str, match_arg) == 0 || match_arg == NULL)) { route_map_rule_delete (&index->match_list, rule); @@ -677,7 +690,7 @@ route_map_delete_set (struct route_map_index *index, const char *set_name, cmd = route_map_lookup_set (set_name); if (cmd == NULL) return 1; - + for (rule = index->set_list.head; rule; rule = rule->next) if ((rule->cmd == cmd) && (rulecmp (rule->rule_str, set_arg) == 0 || set_arg == NULL)) @@ -698,7 +711,7 @@ route_map_delete_set (struct route_map_index *index, const char *set_name, The matrix for a route-map looks like this: (note, this includes the description for the "NEXT" and "GOTO" frobs now - + Match | No Match | permit action | cont @@ -707,22 +720,22 @@ route_map_delete_set (struct route_map_index *index, const char *set_name, | deny deny | cont | - + action) -Apply Set statements, accept route -If Call statement is present jump to the specified route-map, if it denies the route we finish. -If NEXT is specified, goto NEXT statement - -If GOTO is specified, goto the first clause where pref > nextpref + -If GOTO is specified, goto the first clause where seq > goto_seq -If nothing is specified, do as Cisco and finish deny) -Route is denied by route-map. cont) -Goto Next index - + If we get no matches after we've processed all updates, then the route is dropped too. - + Some notes on the new "CALL", "NEXT" and "GOTO" call WORD - If this clause is matched, then the set statements are executed and then we jump to route-map 'WORD'. If @@ -735,7 +748,7 @@ route_map_delete_set (struct route_map_index *index, const char *set_name, first clause greater than this. In order to ensure route-maps *always* exit, you cannot jump backwards. Sorry ;) - + We need to make sure our route-map processing matches the above */ @@ -757,7 +770,7 @@ route_map_apply_match (struct route_map_rule_list *match_list, for (match = match_list->head; match; match = match->next) { /* Try each match statement in turn, If any do not return - RMAP_MATCH, return, otherwise continue on to next match + RMAP_MATCH, return, otherwise continue on to next match statement. All match statements must match for end-result to be a match. */ ret = (*match->cmd->func_apply) (match->value, prefix, @@ -827,7 +840,7 @@ route_map_apply (struct route_map *map, struct prefix *prefix, if (ret == RMAP_DENYMATCH) return ret; } - + switch (index->exitpolicy) { case RMAP_EXIT: @@ -838,9 +851,9 @@ route_map_apply (struct route_map *map, struct prefix *prefix, { /* Find the next clause to jump to */ struct route_map_index *next = index->next; - int nextpref = index->nextpref; + route_map_seq_t goto_seq = index->goto_seq; - while (next && next->pref < nextpref) + while (next && next->seq < goto_seq) { index = next; next = next->next; @@ -898,11 +911,11 @@ route_map_finish (void) vector_free (route_set_vec); route_set_vec = NULL; } - + /* VTY related functions. */ DEFUN (route_map, route_map_cmd, - "route-map WORD (deny|permit) <1-65535>", + "route-map WORD (deny|permit) <1-4294967295>", "Create route-map or enter route-map command mode\n" "Route map tag\n" "Route map denies set operations\n" @@ -910,7 +923,7 @@ DEFUN (route_map, "Sequence to insert to/delete from existing route-map entry\n") { int permit; - unsigned long pref; + unsigned long seq; struct route_map *map; struct route_map_index *index; char *endptr = NULL; @@ -926,26 +939,27 @@ DEFUN (route_map, return CMD_WARNING; } - /* Preference check. */ - pref = strtoul (argv[2], &endptr, 10); - if (pref == ULONG_MAX || *endptr != '\0') + /* Sequence number check. */ + seq = strtoul (argv[2], &endptr, 10); + confirm(sizeof(route_map_seq_t) <= sizeof(unsigned long)) ; + if (seq == ULONG_MAX || *endptr != '\0') { vty_out (vty, "the fourth field must be positive integer%s", VTY_NEWLINE); return CMD_WARNING; } - if (pref == 0 || pref > 65535) + if (seq == 0 || seq > 4294967295) { - vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE); + vty_out (vty, "the fourth field must be <1-4294967295>%s", VTY_NEWLINE); return CMD_WARNING; } /* Get route map. */ map = route_map_get (argv[0]); - index = route_map_index_get (map, permit, pref); + index = route_map_index_get (map, permit, seq); vty->index = index; - vty->node = RMAP_NODE; + vty_set_node(vty, RMAP_NODE) ; return CMD_SUCCESS; } @@ -973,7 +987,7 @@ DEFUN (no_route_map_all, DEFUN (no_route_map, no_route_map_cmd, - "no route-map WORD (deny|permit) <1-65535>", + "no route-map WORD (deny|permit) <1-4294967295>", NO_STR "Create route-map or enter route-map command mode\n" "Route map tag\n" @@ -982,7 +996,7 @@ DEFUN (no_route_map, "Sequence to insert to/delete from existing route-map entry\n") { int permit; - unsigned long pref; + unsigned long seq; struct route_map *map; struct route_map_index *index; char *endptr = NULL; @@ -998,17 +1012,18 @@ DEFUN (no_route_map, return CMD_WARNING; } - /* Preference. */ - pref = strtoul (argv[2], &endptr, 10); - if (pref == ULONG_MAX || *endptr != '\0') + /* Sequence number */ + seq = strtoul (argv[2], &endptr, 10); + confirm(sizeof(route_map_seq_t) <= sizeof(unsigned long)) ; + if (seq == ULONG_MAX || *endptr != '\0') { vty_out (vty, "the fourth field must be positive integer%s", VTY_NEWLINE); return CMD_WARNING; } - if (pref == 0 || pref > 65535) + if (seq == 0 || seq > 4294967295) { - vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE); + vty_out (vty, "the fourth field must be <1-4294967295>%s", VTY_NEWLINE); return CMD_WARNING; } @@ -1022,10 +1037,10 @@ DEFUN (no_route_map, } /* Lookup route map index. */ - index = route_map_index_lookup (map, permit, pref); + index = route_map_index_lookup (map, permit, seq); if (index == NULL) { - vty_out (vty, "%% Could not find route-map entry %s %s%s", + vty_out (vty, "%% Could not find route-map entry %s %s%s", argv[0], argv[2], VTY_NEWLINE); return CMD_WARNING; } @@ -1066,7 +1081,7 @@ DEFUN (no_rmap_onmatch_next, struct route_map_index *index; index = vty->index; - + if (index) index->exitpolicy = RMAP_EXIT; @@ -1075,32 +1090,33 @@ DEFUN (no_rmap_onmatch_next, DEFUN (rmap_onmatch_goto, rmap_onmatch_goto_cmd, - "on-match goto <1-65535>", + "on-match goto <1-4294967295>", "Exit policy on matches\n" "Goto Clause number\n" "Number\n") { struct route_map_index *index = vty->index; - int d = 0; + route_map_seq_t d = 0; if (index) { if (argc == 1 && argv[0]) - VTY_GET_INTEGER_RANGE("route-map index", d, argv[0], 1, 65536); + /* TODO: why did the on-match goto range include 65536 ? */ + VTY_GET_INTEGER_RANGE("route-map index", d, argv[0], 1, 4294967295); else - d = index->pref + 1; - - if (d <= index->pref) + d = index->seq + 1; + + if (d <= index->seq) { /* Can't allow you to do that, Dave */ - vty_out (vty, "can't jump backwards in route-maps%s", + vty_out (vty, "can't jump backwards in route-maps%s", VTY_NEWLINE); return CMD_WARNING; } else { index->exitpolicy = RMAP_GOTO; - index->nextpref = d; + index->goto_seq = d; } } return CMD_SUCCESS; @@ -1119,7 +1135,7 @@ DEFUN (no_rmap_onmatch_goto, if (index) index->exitpolicy = RMAP_EXIT; - + return CMD_SUCCESS; } @@ -1138,13 +1154,13 @@ ALIAS (no_rmap_onmatch_goto, /* GNU Zebra compatible */ ALIAS (rmap_onmatch_goto, rmap_continue_seq_cmd, - "continue <1-65535>", + "continue <1-4294967295>", "Continue on a different entry within the route-map\n" "Route-map entry sequence number\n") ALIAS (no_rmap_onmatch_goto, no_rmap_continue_seq, - "no continue <1-65535>", + "no continue <1-4294967295>", NO_STR "Continue on a different entry within the route-map\n" "Route-map entry sequence number\n") @@ -1164,7 +1180,7 @@ DEFUN (rmap_show_name, ALIAS (rmap_onmatch_goto, rmap_continue_index_cmd, - "continue <1-65536>", + "continue <1-4294967295>", "Exit policy on matches\n" "Goto Clause number\n") @@ -1259,16 +1275,17 @@ route_map_config_write (struct vty *vty) else first = 0; - vty_out (vty, "route-map %s %s %d%s", + vty_out (vty, "route-map %s %s %lu%s", map->name, route_map_type_str (index->type), - index->pref, VTY_NEWLINE); + (unsigned long)index->seq, VTY_NEWLINE); + confirm(sizeof(index->seq) <= sizeof(unsigned long)) ; if (index->description) vty_out (vty, " description %s%s", index->description, VTY_NEWLINE); for (rule = index->match_list.head; rule; rule = rule->next) - vty_out (vty, " match %s %s%s", rule->cmd->str, + vty_out (vty, " match %s %s%s", rule->cmd->str, rule->rule_str ? rule->rule_str : "", VTY_NEWLINE); @@ -1276,13 +1293,16 @@ route_map_config_write (struct vty *vty) vty_out (vty, " set %s %s%s", rule->cmd->str, rule->rule_str ? rule->rule_str : "", VTY_NEWLINE); - if (index->nextrm) - vty_out (vty, " call %s%s", index->nextrm, VTY_NEWLINE); - if (index->exitpolicy == RMAP_GOTO) - vty_out (vty, " on-match goto %d%s", index->nextpref, VTY_NEWLINE); - if (index->exitpolicy == RMAP_NEXT) - vty_out (vty," on-match next%s", VTY_NEWLINE); - + + if (index->nextrm) + vty_out (vty, " call %s%s", index->nextrm, VTY_NEWLINE); + if (index->exitpolicy == RMAP_GOTO) + vty_out (vty, " on-match goto %lu%s", (unsigned long)index->goto_seq, + VTY_NEWLINE); + confirm(sizeof(index->goto_seq) <= sizeof(unsigned long)) ; + if (index->exitpolicy == RMAP_NEXT) + vty_out (vty," on-match next%s", VTY_NEWLINE); + write++; } return write; @@ -1315,12 +1335,12 @@ route_map_init_vty (void) install_element (RMAP_NODE, &no_rmap_onmatch_next_cmd); install_element (RMAP_NODE, &rmap_onmatch_goto_cmd); install_element (RMAP_NODE, &no_rmap_onmatch_goto_cmd); - + /* Install the continue stuff (ALIAS of on-match). */ install_element (RMAP_NODE, &rmap_continue_cmd); install_element (RMAP_NODE, &no_rmap_continue_cmd); install_element (RMAP_NODE, &rmap_continue_index_cmd); - + /* Install the call stuff. */ install_element (RMAP_NODE, &rmap_call_cmd); install_element (RMAP_NODE, &no_rmap_call_cmd); @@ -1328,7 +1348,7 @@ route_map_init_vty (void) /* Install description commands. */ install_element (RMAP_NODE, &rmap_description_cmd); install_element (RMAP_NODE, &no_rmap_description_cmd); - + /* Install show command */ install_element (ENABLE_NODE, &rmap_show_name_cmd); } |