diff options
author | paul <paul> | 2004-09-13 05:12:46 +0000 |
---|---|---|
committer | paul <paul> | 2004-09-13 05:12:46 +0000 |
commit | fee0f4c629412f422fc9a857e097ef335c2c576c (patch) | |
tree | 14703e303ea2cecaee7728d9ee27075b0590a679 /lib/routemap.c | |
parent | 0e82d0e1204e45ecce773a7e19f7d64140f7a66a (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.c | 131 |
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); |