summaryrefslogtreecommitdiffstats
path: root/lib/routemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/routemap.c')
-rw-r--r--lib/routemap.c206
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);
}