summaryrefslogtreecommitdiffstats
path: root/lib/routemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/routemap.c')
-rw-r--r--lib/routemap.c117
1 files changed, 67 insertions, 50 deletions
diff --git a/lib/routemap.c b/lib/routemap.c
index b000f2fc..4e65fa2b 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -634,72 +634,85 @@ route_map_delete_set (struct route_map_index *index, char *set_name,
return 1;
}
-/* Apply route map's each index to the object. */
-/*
-** 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 a | c
-** |
-** ------------------+---------------
-** |
-** deny b | d
-** |
-**
-** a) Apply Set statements, accept route
-** If NEXT is specified, goto NEXT statement
-** If GOTO is specified, goto the first clause where pref > nextpref
-** If nothing is specified, do as Cisco and finish
-** b) Finish route-map processing, and deny route
-** c) & d) 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 "NEXT" and "GOTO"
-** on-match next - If this clause is matched, then the set statements
-** are executed and then we drop through to the next clause
-** on-match goto n - If this clause is matched, then the set statments
-** are executed and then we goto the nth clause, or the
-** 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
+/* Apply route map's each index to the object.
+
+ 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 a | c
+ |
+ ------------------+---------------
+ |
+ deny b | d
+ |
+
+ a) Apply Set statements, accept route
+ If NEXT is specified, goto NEXT statement
+ If GOTO is specified, goto the first clause where pref > nextpref
+ If nothing is specified, do as Cisco and finish
+ b) If NEXT is specified, goto NEXT statement
+ If nothing is specified, finally will be denied by route-map.
+ c) & d) 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 "NEXT" and "GOTO"
+ on-match next - If this clause is matched, then the set statements
+ are executed and then we drop through to the next clause
+ on-match goto n - If this clause is matched, then the set statments
+ are executed and then we goto the nth clause, or the
+ 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
*/
route_map_result_t
route_map_apply_index (struct route_map_index *index, struct prefix *prefix,
route_map_object_t type, void *object)
{
- int ret;
+ int ret = 0;
struct route_map_rule *match;
struct route_map_rule *set;
-
- /* Check all match rule and if there is no match rule return 0. */
- for (match = index->match_list.head; match; match = match->next)
+
+ /* Check all match rule and if there is no match rule, go to the
+ set statement. */
+ if (! index->match_list.head)
+ ret = RMAP_MATCH;
+ else
{
- /* Try each match statement in turn. If any return something
- other than RM_MATCH then we don't need to check anymore and can
- return */
- ret = (*match->cmd->func_apply)(match->value, prefix, type, object);
- if (ret != RMAP_MATCH)
- return ret;
+ for (match = index->match_list.head; match; match = match->next)
+ {
+ /* Try each match statement in turn, If any return
+ RMAP_MATCH, go direct to set statement, otherwise, walk
+ to next match statement. */
+ ret = (*match->cmd->func_apply)(match->value, prefix, type, object);
+
+ if (ret == RMAP_MATCH)
+ break;
+ }
}
+ /* If end of match statement, still can't get any RMAP_MATCH return,
+ just return to next rout-map statement. */
+
+ if (ret != RMAP_MATCH)
+ return ret;
+
/* We get here if all match statements matched From the matrix
- above, if this is PERMIT we go on and apply the SET functions. If
- we're deny, we return indicating we matched a deny */
+ above, if this is PERMIT we go on and apply the SET functions.
+ If we're deny, we return indicating we matched a deny */
/* Apply set statement to the object. */
if (index->type == RMAP_PERMIT)
{
for (set = index->set_list.head; set; set = set->next)
- {
- ret = (*set->cmd->func_apply)(set->value, prefix, type, object);
- }
+ ret = (*set->cmd->func_apply)(set->value, prefix, type, object);
+
return RMAP_MATCH;
}
else
@@ -726,11 +739,15 @@ route_map_apply (struct route_map *map, struct prefix *prefix,
/* Apply this index. End here if we get a RM_NOMATCH */
ret = route_map_apply_index (index, prefix, type, object);
+ if (ret == RMAP_MATCH || ret == RMAP_DENYMATCH)
+ return ret;
+
if (ret != RMAP_NOMATCH)
{
/* We now have to handle the NEXT and GOTO clauses */
if(index->exitpolicy == RMAP_EXIT)
return ret;
+
if(index->exitpolicy == RMAP_GOTO)
{
/* Find the next clause to jump to */