summaryrefslogtreecommitdiff
path: root/lib/routemap.c
diff options
context:
space:
mode:
authorpaul <paul>2004-09-13 05:12:46 +0000
committerpaul <paul>2004-09-13 05:12:46 +0000
commitfee0f4c629412f422fc9a857e097ef335c2c576c (patch)
tree14703e303ea2cecaee7728d9ee27075b0590a679 /lib/routemap.c
parent0e82d0e1204e45ecce773a7e19f7d64140f7a66a (diff)
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
Diffstat (limited to 'lib/routemap.c')
-rw-r--r--lib/routemap.c131
1 files changed, 113 insertions, 18 deletions
diff --git a/lib/routemap.c b/lib/routemap.c
index 9995334e..9d6bbcfd 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -26,6 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "prefix.h"
#include "routemap.h"
#include "command.h"
+#include "log.h"
/* Vector for route match rules. */
static vector route_match_vec;
@@ -221,9 +222,11 @@ vty_show_route_map_entry (struct vty *vty, struct route_map *map)
rule->cmd->str, rule->rule_str, VTY_NEWLINE);
vty_out (vty, " Action:%s", VTY_NEWLINE);
- if (index->exitpolicy == RMAP_GOTO)
+
+ if (index->nextrm)
+ vty_out (vty, " Call %s%s", index->nextrm, VTY_NEWLINE);
+ else if (index->exitpolicy == RMAP_GOTO)
vty_out (vty, " Goto %d%s", index->nextpref, VTY_NEWLINE);
-
else if (index->exitpolicy == RMAP_NEXT)
{
vty_out (vty, " Goto next, (entry ");
@@ -298,6 +301,10 @@ route_map_index_delete (struct route_map_index *index, int notify)
else
index->map->head = index->next;
+ /* Free 'char *nextrm' if not NULL */
+ if (index->nextrm)
+ free (index->nextrm);
+
/* Execute event hook. */
if (route_map_master.event_hook && notify)
(*route_map_master.event_hook) (RMAP_EVENT_INDEX_DELETED,
@@ -688,18 +695,26 @@ route_map_delete_set (struct route_map_index *index, char *set_name,
deny deny | cont
|
- action) 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
- deny) If NEXT is specified, goto NEXT statement
- If nothing is specified, finally will be denied by route-map.
- cont) Goto Next index
+ 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 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 "NEXT" and "GOTO"
+ 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
+ this route-map denies the route, we finish, in other case we
+ do whatever the exit policy (EXIT, NEXT or GOTO) tells.
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
@@ -746,10 +761,20 @@ route_map_result_t
route_map_apply (struct route_map *map, struct prefix *prefix,
route_map_object_t type, void *object)
{
+ static int recursion = 0;
int ret = 0;
struct route_map_index *index;
struct route_map_rule *set;
+ if (recursion > RMAP_RECURSION_LIMIT)
+ {
+ zlog (NULL, LOG_WARNING,
+ "route-map recursion limit (%d) reached, discarding route",
+ RMAP_RECURSION_LIMIT);
+ recursion = 0;
+ return RMAP_DENYMATCH;
+ }
+
if (map == NULL)
return RMAP_DENYMATCH;
@@ -771,6 +796,25 @@ route_map_apply (struct route_map *map, struct prefix *prefix,
for (set = index->set_list.head; set; set = set->next)
ret = (*set->cmd->func_apply) (set->value, prefix,
type, object);
+
+ /* Call another route-map if available */
+ if (index->nextrm)
+ {
+ struct route_map *nextrm =
+ route_map_lookup_by_name (index->nextrm);
+
+ if (nextrm) /* Target route-map found, jump to it */
+ {
+ recursion++;
+ ret = route_map_apply (nextrm, prefix, type, object);
+ recursion--;
+ }
+
+ /* If nextrm returned 'deny', finish. */
+ if (ret == RMAP_DENYMATCH)
+ return ret;
+ }
+
switch (index->exitpolicy)
{
case RMAP_EXIT:
@@ -781,8 +825,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;
- while (next && next->pref < index->nextpref)
+ while (next && next->pref < nextpref)
{
index = next;
next = next->next;
@@ -798,9 +843,6 @@ route_map_apply (struct route_map *map, struct prefix *prefix,
else if (index->type == RMAP_DENY)
/* 'deny' */
{
- if (index->exitpolicy == RMAP_NEXT)
- continue;
- else
return RMAP_DENYMATCH;
}
}
@@ -1046,7 +1088,7 @@ DEFUN (no_rmap_onmatch_goto,
"no on-match goto",
NO_STR
"Exit policy on matches\n"
- "Next clause\n")
+ "Goto Clause number\n")
{
struct route_map_index *index;
@@ -1103,6 +1145,49 @@ DEFUN (rmap_show_name,
return vty_show_route_map (vty, argv[0]);
}
+ALIAS (rmap_onmatch_goto,
+ rmap_continue_index_cmd,
+ "continue <1-65536>",
+ "Exit policy on matches\n"
+ "Goto Clause number\n")
+
+DEFUN (rmap_call,
+ rmap_call_cmd,
+ "call WORD",
+ "Jump to another Route-Map after match+set\n"
+ "Target route-map name\n")
+{
+ struct route_map_index *index;
+
+ index = vty->index;
+ if (index)
+ {
+ if (index->nextrm)
+ free (index->nextrm);
+ index->nextrm = strdup (argv[0]);
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_rmap_call,
+ no_rmap_call_cmd,
+ "no call",
+ NO_STR
+ "Jump to another Route-Map after match+set\n")
+{
+ struct route_map_index *index;
+
+ index = vty->index;
+
+ if (index->nextrm)
+ {
+ free (index->nextrm);
+ index->nextrm = NULL;
+ }
+
+ return CMD_SUCCESS;
+}
+
/* Configuration write function. */
int
route_map_config_write (struct vty *vty)
@@ -1135,9 +1220,10 @@ 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);
+ 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);
@@ -1173,7 +1259,16 @@ route_map_init_vty ()
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);
+
/* Install show command */
install_element (ENABLE_NODE, &rmap_show_cmd);
install_element (ENABLE_NODE, &rmap_show_name_cmd);