summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_routemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_routemap.c')
-rw-r--r--bgpd/bgp_routemap.c1038
1 files changed, 878 insertions, 160 deletions
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 39fa08c8..18ecc6c8 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -39,12 +39,15 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#endif /* HAVE_LIBPCREPOSIX */
#include "buffer.h"
#include "sockunion.h"
+#include "hash.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_aspath.h"
+#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_clist.h"
@@ -52,6 +55,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_debug.h"
+
/* Memo of route-map commands.
@@ -59,7 +64,7 @@ o Cisco route-map
match as-path : Done
community : Done
- interface : Not yet
+ interface : Done
ip address : Done
ip next-hop : Done
ip route-source : Done
@@ -71,7 +76,8 @@ o Cisco route-map
length : (This will not be implemented by bgpd)
metric : Done
route-type : (This will not be implemented by bgpd)
- tag : (This will not be implemented by bgpd)
+ tag : Done
+ local-preference : Done
set as-path prepend : Done
as-path tag : Not yet
@@ -90,7 +96,7 @@ o Cisco route-map
metric : Done
metric-type : Not yet
origin : Done
- tag : (This will not be implemented by bgpd)
+ tag : Done
weight : Done
o Local extensions
@@ -613,6 +619,72 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
route_match_ip_route_source_prefix_list_free
};
+/* `match local-preference LOCAL-PREF' */
+
+/* Match function return 1 if match is success else return zero. */
+static route_map_result_t
+route_match_local_pref (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ u_int32_t *local_pref;
+ struct bgp_info *bgp_info;
+
+ if (type == RMAP_BGP)
+ {
+ local_pref = rule;
+ bgp_info = object;
+
+ if (bgp_info->attr->local_pref == *local_pref)
+ return RMAP_MATCH;
+ else
+ return RMAP_NOMATCH;
+ }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `match local-preference' match statement.
+ `arg' is local-pref value */
+static void *
+route_match_local_pref_compile (const char *arg)
+{
+ u_int32_t *local_pref;
+ char *endptr = NULL;
+ unsigned long tmpval;
+
+ /* Locpref value shoud be integer. */
+ if (! all_digit (arg))
+ return NULL;
+
+ errno = 0;
+ tmpval = strtoul (arg, &endptr, 10);
+ if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
+ return NULL;
+
+ local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
+
+ if (!local_pref)
+ return local_pref;
+
+ *local_pref = tmpval;
+ return local_pref;
+}
+
+/* Free route map's compiled `match local-preference' value. */
+static void
+route_match_local_pref_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for metric matching. */
+struct route_map_rule_cmd route_match_local_pref_cmd =
+{
+ "local-preference",
+ route_match_local_pref,
+ route_match_local_pref_compile,
+ route_match_local_pref_free
+};
+
/* `match metric METRIC' */
/* Match function return 1 if match is success else return zero. */
@@ -657,9 +729,9 @@ route_match_aspath (void *rule, struct prefix *prefix,
as_list = as_list_lookup ((char *) rule);
if (as_list == NULL)
return RMAP_NOMATCH;
-
+
bgp_info = object;
-
+
/* Perform match. */
return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
}
@@ -933,10 +1005,127 @@ struct route_map_rule_cmd route_match_probability_cmd =
route_match_probability_free
};
+/* `match interface IFNAME' */
+/* Match function should return 1 if match is success else return
+ zero. */
+static route_map_result_t
+route_match_interface (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ struct interface *ifp;
+ struct bgp_info *info;
+
+ if (type == RMAP_BGP)
+ {
+ info = object;
+
+ if (!info || !info->attr)
+ return RMAP_NOMATCH;
+
+ ifp = if_lookup_by_name ((char *)rule);
+
+ if (ifp == NULL || ifp->ifindex != info->attr->nh_ifindex)
+ return RMAP_NOMATCH;
+
+ return RMAP_MATCH;
+ }
+ return RMAP_NOMATCH;
+}
+
+/* Route map `interface' match statement. `arg' should be
+ interface name. */
+static void *
+route_match_interface_compile (const char *arg)
+{
+ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+/* Free route map's compiled `interface' value. */
+static void
+route_match_interface_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for ip address matching. */
+struct route_map_rule_cmd route_match_interface_cmd =
+{
+ "interface",
+ route_match_interface,
+ route_match_interface_compile,
+ route_match_interface_free
+};
+
/* } */
/* `set ip next-hop IP_ADDRESS' */
+/* Match function return 1 if match is success else return zero. */
+static route_map_result_t
+route_match_tag (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ u_short *tag;
+ struct bgp_info *bgp_info;
+
+ if (type == RMAP_BGP)
+ {
+ tag = rule;
+ bgp_info = object;
+
+ if (!bgp_info->attr->extra)
+ return RMAP_NOMATCH;
+
+ return ((bgp_info->attr->extra->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH);
+ }
+
+ return RMAP_NOMATCH;
+}
+
+
+/* Route map `match tag' match statement. `arg' is TAG value */
+static void *
+route_match_tag_compile (const char *arg)
+{
+ u_short *tag;
+ u_short tmp;
+
+ /* tag value shoud be integer. */
+ if (! all_digit (arg))
+ return NULL;
+
+ tmp = atoi(arg);
+ if (tmp < 1)
+ return NULL;
+
+ tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
+
+ if (!tag)
+ return tag;
+
+ *tag = tmp;
+
+ return tag;
+}
+
+
+/* Free route map's compiled 'match tag' value. */
+static void
+route_match_tag_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for tag matching. */
+struct route_map_rule_cmd route_match_tag_cmd =
+{
+ "tag",
+ route_match_tag,
+ route_match_tag_compile,
+ route_match_tag_free,
+};
+
+
/* Set nexthop to object. ojbect must be pointer to struct attr. */
struct rmap_ip_nexthop_set
{
@@ -1710,6 +1899,73 @@ struct route_map_rule_cmd route_set_aggregator_as_cmd =
route_set_aggregator_as_free,
};
+/* Set tag to object. object must be pointer to struct bgp_info */
+static route_map_result_t
+route_set_tag (void *rule, struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ u_short *tag;
+ struct bgp_info *bgp_info;
+ struct attr_extra *ae;
+
+ if (type == RMAP_BGP)
+ {
+ tag = rule;
+ bgp_info = object;
+ ae = bgp_attr_extra_get (bgp_info->attr);
+
+ /* Set tag value */
+ ae->tag=*tag;
+
+ }
+
+ return RMAP_OKAY;
+}
+
+/* Route map `tag' compile function. Given string is converted to u_short. */
+static void *
+route_set_tag_compile (const char *arg)
+{
+ u_short *tag;
+ u_short tmp;
+
+ /* tag value shoud be integer. */
+ if (! all_digit (arg))
+ return NULL;
+
+ tmp = atoi(arg);
+
+ if (tmp < 1)
+ return NULL;
+
+ tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
+
+ if (!tag)
+ return tag;
+
+ *tag = tmp;
+
+ return tag;
+}
+
+/* Free route map's tag value. */
+static void
+route_set_tag_free (void *rule)
+{
+ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+
+/* Route map commands for tag set. */
+struct route_map_rule_cmd route_set_tag_cmd =
+{
+ "tag",
+ route_set_tag,
+ route_set_tag_compile,
+ route_set_tag_free,
+};
+
+
/* `match ipv6 address IP_ACCESS_LIST' */
static route_map_result_t
@@ -2187,7 +2443,8 @@ struct route_map_rule_cmd route_set_originator_id_cmd =
/* Add bgp route map rule. */
static int
bgp_route_match_add (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
+ const char *command, const char *arg,
+ route_map_event_t type)
{
int ret;
@@ -2197,36 +2454,71 @@ bgp_route_match_add (struct vty *vty, struct route_map_index *index,
switch (ret)
{
case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
return CMD_WARNING;
case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
+
+ if (type != RMAP_EVENT_MATCH_ADDED)
+ {
+ route_map_upd8_dependency (type, arg, index->map->name);
+ }
+
return CMD_SUCCESS;
}
/* Delete bgp route map rule. */
static int
bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
- const char *command, const char *arg)
+ const char *command, const char *arg,
+ route_map_event_t type)
{
int ret;
+ char *dep_name = (char *)arg;
+ const char *tmpstr;
+ char *rmap_name = NULL;
+
+ if (type != RMAP_EVENT_MATCH_DELETED)
+ {
+ /* ignore the mundane, the types without any dependency */
+ if (arg == NULL)
+ {
+ if ((tmpstr = route_map_get_match_arg(index, command)) != NULL)
+ dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
+ }
+ rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
+ }
- ret = route_map_delete_match (index, command, arg);
+ ret = route_map_delete_match (index, command, dep_name);
if (ret)
{
switch (ret)
{
case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
- return CMD_WARNING;
+ vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
+ break;
case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
- return CMD_WARNING;
+ vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
+ break;
}
+ if (arg == NULL && dep_name)
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ if (rmap_name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+ return CMD_WARNING;
}
+
+ if (type != RMAP_EVENT_MATCH_DELETED && dep_name)
+ route_map_upd8_dependency(type, dep_name, rmap_name);
+
+ if (arg == NULL && dep_name)
+ XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+ if (rmap_name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+
return CMD_SUCCESS;
}
@@ -2243,10 +2535,10 @@ bgp_route_set_add (struct vty *vty, struct route_map_index *index,
switch (ret)
{
case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
return CMD_WARNING;
case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
@@ -2266,134 +2558,363 @@ bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
switch (ret)
{
case RMAP_RULE_MISSING:
- vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
+ vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
return CMD_WARNING;
case RMAP_COMPILE_ERROR:
- vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+ vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
return CMD_SUCCESS;
}
-/* Hook function for updating route_map assignment. */
+/*
+ * This is the workhorse routine for processing in/out/import/export routemap
+ * modifications.
+ */
static void
-bgp_route_map_update (const char *unused)
+bgp_route_map_process_peer (const char *rmap_name, struct peer *peer,
+ int afi, int safi, int route_update)
{
- int i;
- afi_t afi;
- safi_t safi;
- int direct;
- struct listnode *node, *nnode;
- struct listnode *mnode, *mnnode;
- struct bgp *bgp;
- struct peer *peer;
- struct peer_group *group;
+
+ int update;
struct bgp_filter *filter;
- struct bgp_node *bn;
- struct bgp_static *bgp_static;
if (bm->bgp == NULL) /* may be called during cleanup */
return;
- /* For neighbor route-map updates. */
- for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
+ if (!peer || !rmap_name)
+ return;
+
+ filter = &peer->filter[afi][safi];
+ /*
+ * in is for non-route-server clients,
+ * import/export is for route-server clients,
+ * out is for all peers
+ */
+ if (!CHECK_FLAG(peer->flags, PEER_FLAG_RSERVER_CLIENT))
{
- for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+ if (filter->map[RMAP_IN].name &&
+ (strcmp(rmap_name, filter->map[RMAP_IN].name) == 0))
{
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- {
- filter = &peer->filter[afi][safi];
-
- for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
- {
- if (filter->map[direct].name)
- filter->map[direct].map =
- route_map_lookup_by_name (filter->map[direct].name);
- else
- filter->map[direct].map = NULL;
- }
-
- if (filter->usmap.name)
- filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
- else
- filter->usmap.map = NULL;
- }
+ filter->map[RMAP_IN].map =
+ route_map_lookup_by_name (filter->map[RMAP_IN].name);
+
+ if (route_update && peer->status == Established)
+ {
+ if (CHECK_FLAG (peer->af_flags[afi][safi],
+ PEER_FLAG_SOFT_RECONFIG))
+ {
+ if (bgp_debug_update(peer, NULL, 1))
+ zlog_debug("Processing route_map %s update on "
+ "peer %s (inbound, soft-reconfig)",
+ rmap_name, peer->host);
+
+ bgp_soft_reconfig_in (peer, afi, safi);
+ }
+ else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
+ || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
+ {
+
+ if (bgp_debug_update(peer, NULL, 1))
+ zlog_debug("Processing route_map %s update on "
+ "peer %s (inbound, route-refresh)",
+ rmap_name, peer->host);
+ bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
+ }
+ }
+ }
+ }
+
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_RSERVER_CLIENT))
+ {
+ update = 0;
+
+ if (filter->map[RMAP_IMPORT].name &&
+ (strcmp(rmap_name, filter->map[RMAP_IMPORT].name) == 0))
+ {
+ filter->map[RMAP_IMPORT].map =
+ route_map_lookup_by_name (filter->map[RMAP_IMPORT].name);
+ update = 1;
}
- for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
+
+ if (filter->map[RMAP_EXPORT].name &&
+ (strcmp(rmap_name, filter->map[RMAP_EXPORT].name) == 0))
{
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- {
- filter = &group->conf->filter[afi][safi];
-
- for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
- {
- if (filter->map[direct].name)
- filter->map[direct].map =
- route_map_lookup_by_name (filter->map[direct].name);
- else
- filter->map[direct].map = NULL;
- }
-
- if (filter->usmap.name)
- filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
- else
- filter->usmap.map = NULL;
- }
+ filter->map[RMAP_EXPORT].map =
+ route_map_lookup_by_name (filter->map[RMAP_EXPORT].name);
+
+ update = 1;
+ }
+
+ if (update && route_update && peer->status == Established)
+ {
+ if (CHECK_FLAG (peer->af_flags[afi][safi],
+ PEER_FLAG_SOFT_RECONFIG))
+ {
+ if (bgp_debug_update(peer, NULL, 1))
+ zlog_debug("Processing route_map %s update on "
+ "peer %s (import, soft-reconfig)",
+ rmap_name, peer->host);
+
+ bgp_soft_reconfig_in (peer, afi, safi);
+ }
+ else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
+ || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
+ {
+ if (bgp_debug_update(peer, NULL, 1))
+ zlog_debug("Processing route_map %s update on "
+ "peer %s (import, route-refresh)",
+ rmap_name, peer->host);
+ bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
+ }
+ /* DD: Else, what else do we do ? Reset peer ? */
}
}
- /* For default-originate route-map updates. */
- for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
- {
- for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+ if (filter->map[RMAP_OUT].name &&
+ (strcmp(rmap_name, filter->map[RMAP_OUT].name) == 0))
{
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- {
- if (peer->default_rmap[afi][safi].name)
- peer->default_rmap[afi][safi].map =
- route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
- else
- peer->default_rmap[afi][safi].map = NULL;
- }
+ filter->map[RMAP_OUT].map =
+ route_map_lookup_by_name (filter->map[RMAP_OUT].name);
+
+ if (bgp_debug_update(peer, NULL, 0))
+ zlog_debug("Processing route_map %s update on peer %s (outbound)",
+ rmap_name, peer->host);
+
+ if (route_update)
+ bgp_announce_route_all(peer);
}
+
+ if (filter->usmap.name &&
+ (strcmp(rmap_name, filter->usmap.name) == 0))
+ {
+ filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
+ if (route_update)
+ bgp_announce_route_all(peer);
}
+}
- /* For network route-map updates. */
- for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
+static void
+bgp_route_map_update_peer_group(const char *rmap_name, struct bgp *bgp)
+{
+ struct peer_group *group;
+ struct listnode *node, *nnode;
+ struct bgp_filter *filter;
+ int afi, safi;
+ int direct;
+
+ if (!bgp)
+ return;
+
+ /* All the peers have been updated correctly already. This is
+ * just updating the placeholder data. No real update required.
+ */
+ for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ {
+ filter = &group->conf->filter[afi][safi];
+
+ for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
+ {
+ if ((filter->map[direct].name) &&
+ (strcmp(rmap_name, filter->map[direct].name) == 0))
+ filter->map[direct].map =
+ route_map_lookup_by_name (filter->map[direct].name);
+ }
+
+ if (filter->usmap.name &&
+ (strcmp(rmap_name, filter->usmap.name) == 0))
+ filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
+ }
+}
+
+static int
+bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update)
+{
+ int i;
+ afi_t afi;
+ safi_t safi;
+ struct peer *peer;
+ struct bgp_node *bn;
+ struct bgp_static *bgp_static;
+ struct bgp *bgp = (struct bgp *)arg;
+ struct listnode *node, *nnode;
+ char buf[INET6_ADDRSTRLEN];
+
+ if (!bgp)
+ return -1;
+
+ for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
+
+ /* Ignore dummy peer-group structure */
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
+ continue;
+
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
- bn = bgp_route_next (bn))
- if ((bgp_static = bn->info) != NULL)
+ {
+ /* Ignore inactive AFI/SAFI */
+ if (! peer->afc[afi][safi])
+ continue;
+
+ /* process in/out/import/export route-maps */
+ bgp_route_map_process_peer(rmap_name, peer, afi, safi, route_update);
+
+ /* process default-originate route-map */
+ if (peer->default_rmap[afi][safi].name &&
+ (strcmp (rmap_name, peer->default_rmap[afi][safi].name) == 0))
{
- if (bgp_static->rmap.name)
- bgp_static->rmap.map =
- route_map_lookup_by_name (bgp_static->rmap.name);
- else
- bgp_static->rmap.map = NULL;
+ peer->default_rmap[afi][safi].map =
+ route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
+
+ if (bgp_debug_update(peer, NULL, 0))
+ zlog_debug("Processing route_map %s update on "
+ "default-originate", rmap_name);
+
+ if (route_update)
+ bgp_default_originate (peer, afi, safi, 0);
}
+ }
}
+ bgp_route_map_update_peer_group(rmap_name, bgp);
+
+ /* For table route-map updates. */
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ {
+ if (bgp->table_map[afi][safi].name &&
+ (strcmp(rmap_name, bgp->table_map[afi][safi].name) == 0))
+ {
+ bgp->table_map[afi][safi].map =
+ route_map_lookup_by_name (bgp->table_map[afi][safi].name);
+ if (BGP_DEBUG (zebra, ZEBRA))
+ zlog_debug("Processing route_map %s update on "
+ "table map", rmap_name);
+ if (route_update)
+ bgp_zebra_announce_table(bgp, afi, safi);
+ }
+ }
+
+ /* For network route-map updates. */
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
+ bn = bgp_route_next (bn))
+ if ((bgp_static = bn->info) != NULL)
+ {
+ if (bgp_static->rmap.name &&
+ (strcmp(rmap_name, bgp_static->rmap.name) == 0))
+ {
+ bgp_static->rmap.map =
+ route_map_lookup_by_name (bgp_static->rmap.name);
+ if (route_update)
+ if (!bgp_static->backdoor)
+ {
+ if (bgp_debug_zebra(&bn->p))
+ zlog_debug("Processing route_map %s update on "
+ "static route %s", rmap_name,
+ inet_ntop (bn->p.family, &bn->p.u.prefix,
+ buf, INET6_ADDRSTRLEN));
+ bgp_static_update (bgp, &bn->p, bgp_static, afi, safi);
+ }
+ }
+ }
+
/* For redistribute route-map updates. */
- for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
+ {
+ if (bgp->rmap[afi][i].name &&
+ (strcmp(rmap_name, bgp->rmap[afi][i].name) == 0))
+ {
+ bgp->rmap[afi][i].map =
+ route_map_lookup_by_name (bgp->rmap[afi][i].name);
+
+ if (bgp->redist[afi][i] && route_update)
+ {
+ if (BGP_DEBUG (zebra, ZEBRA))
+ zlog_debug("Processing route_map %s update on "
+ "redistributed routes", rmap_name);
+
+ bgp_redistribute_resend (bgp, afi, i);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+bgp_route_map_process_update_cb (void *arg, char *rmap_name)
+{
+ return bgp_route_map_process_update (arg, rmap_name, 1);
+}
+
+int
+bgp_route_map_update_timer(struct thread *thread)
+{
+ struct bgp *bgp = THREAD_ARG(thread);
+
+ bgp->t_rmap_update = NULL;
+
+ route_map_walk_update_list((void *)bgp, bgp_route_map_process_update_cb);
+
+ return (0);
+}
+
+static void
+bgp_route_map_mark_update (const char *rmap_name)
+{
+ struct listnode *node, *nnode;
+ struct bgp *bgp;
+
+ for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
+ if (bgp->t_rmap_update == NULL)
{
- if (bgp->rmap[AFI_IP][i].name)
- bgp->rmap[AFI_IP][i].map =
- route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
- if (bgp->rmap[AFI_IP6][i].name)
- bgp->rmap[AFI_IP6][i].map =
- route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
+ /* rmap_update_timer of 0 means don't do route updates */
+ if (bgp->rmap_update_timer)
+ bgp->t_rmap_update =
+ thread_add_timer(bm->master, bgp_route_map_update_timer, bgp,
+ bgp->rmap_update_timer);
+ else
+ bgp_route_map_process_update((void *)bgp, rmap_name, 0);
}
}
}
+static void
+bgp_route_map_add (const char *rmap_name)
+{
+ if (route_map_mark_updated(rmap_name, 0) == 0)
+ bgp_route_map_mark_update(rmap_name);
+
+ route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
+}
+
+static void
+bgp_route_map_delete (const char *rmap_name)
+{
+ if (route_map_mark_updated(rmap_name, 1) == 0)
+ bgp_route_map_mark_update(rmap_name);
+
+ route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
+}
+
+static void
+bgp_route_map_event (route_map_event_t event, const char *rmap_name)
+{
+ if (route_map_mark_updated(rmap_name, 0) == 0)
+ bgp_route_map_mark_update(rmap_name);
+
+ route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
+}
+
+
DEFUN (match_peer,
match_peer_cmd,
"match peer (A.B.C.D|X:X::X:X)",
@@ -2402,7 +2923,8 @@ DEFUN (match_peer,
"IPv6 address of peer\n"
"IP address of peer\n")
{
- return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "peer", argv[0],
+ RMAP_EVENT_MATCH_ADDED);
}
DEFUN (match_peer_local,
@@ -2412,7 +2934,8 @@ DEFUN (match_peer_local,
"Match peer address\n"
"Static or Redistributed routes\n")
{
- return bgp_route_match_add (vty, vty->index, "peer", "local");
+ return bgp_route_match_add (vty, vty->index, "peer", "local",
+ RMAP_EVENT_MATCH_DELETED);
}
DEFUN (no_match_peer,
@@ -2423,9 +2946,11 @@ DEFUN (no_match_peer,
"Match peer address\n")
{
if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "peer", NULL);
+ return bgp_route_match_delete (vty, vty->index, "peer", NULL,
+ RMAP_EVENT_MATCH_DELETED);
- return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "peer", argv[0],
+ RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_peer,
@@ -2455,7 +2980,8 @@ DEFUN (match_ip_address,
"IP access-list number (expanded range)\n"
"IP Access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ip address", argv[0],
+ RMAP_EVENT_FILTER_ADDED);
}
DEFUN (no_match_ip_address,
@@ -2467,9 +2993,11 @@ DEFUN (no_match_ip_address,
"Match address of route\n")
{
if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
+ return bgp_route_match_delete (vty, vty->index, "ip address", NULL,
+ RMAP_EVENT_FILTER_DELETED);
- return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ip address", argv[0],
+ RMAP_EVENT_FILTER_DELETED);
}
ALIAS (no_match_ip_address,
@@ -2493,7 +3021,8 @@ DEFUN (match_ip_next_hop,
"IP access-list number (expanded range)\n"
"IP Access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0],
+ RMAP_EVENT_FILTER_ADDED);
}
DEFUN (no_match_ip_next_hop,
@@ -2505,9 +3034,11 @@ DEFUN (no_match_ip_next_hop,
"Match next-hop address of route\n")
{
if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
+ return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL,
+ RMAP_EVENT_FILTER_DELETED);
- return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0],
+ RMAP_EVENT_FILTER_DELETED);
}
ALIAS (no_match_ip_next_hop,
@@ -2530,7 +3061,8 @@ DEFUN (match_probability,
"Match portion of routes defined by percentage value\n"
"Percentage of routes\n")
{
- return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "probability", argv[0],
+ RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_probability,
@@ -2540,7 +3072,8 @@ DEFUN (no_match_probability,
MATCH_STR
"Match portion of routes defined by percentage value\n")
{
- return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
+ return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL,
+ RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_probability,
@@ -2563,7 +3096,8 @@ DEFUN (match_ip_route_source,
"IP access-list number (expanded range)\n"
"IP standard access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0],
+ RMAP_EVENT_FILTER_ADDED);
}
DEFUN (no_match_ip_route_source,
@@ -2575,9 +3109,11 @@ DEFUN (no_match_ip_route_source,
"Match advertising source address of route\n")
{
if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
+ return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL,
+ RMAP_EVENT_FILTER_DELETED);
- return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ip route-source",
+ argv[0], RMAP_EVENT_FILTER_DELETED);
}
ALIAS (no_match_ip_route_source,
@@ -2600,7 +3136,8 @@ DEFUN (match_ip_address_prefix_list,
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ip address prefix-list",
+ argv[0], RMAP_EVENT_PLIST_ADDED);
}
DEFUN (no_match_ip_address_prefix_list,
@@ -2612,10 +3149,9 @@ DEFUN (no_match_ip_address_prefix_list,
"Match address of route\n"
"Match entries of prefix-lists\n")
{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
-
- return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ip address prefix-list",
+ argc == 0 ? NULL : argv[0],
+ RMAP_EVENT_PLIST_DELETED);
}
ALIAS (no_match_ip_address_prefix_list,
@@ -2637,7 +3173,8 @@ DEFUN (match_ip_next_hop_prefix_list,
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list",
+ argv[0], RMAP_EVENT_PLIST_ADDED);
}
DEFUN (no_match_ip_next_hop_prefix_list,
@@ -2649,10 +3186,9 @@ DEFUN (no_match_ip_next_hop_prefix_list,
"Match next-hop address of route\n"
"Match entries of prefix-lists\n")
{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
-
- return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
+ argc == 0 ? NULL : argv[0],
+ RMAP_EVENT_PLIST_DELETED);
}
ALIAS (no_match_ip_next_hop_prefix_list,
@@ -2674,7 +3210,8 @@ DEFUN (match_ip_route_source_prefix_list,
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list",
+ argv[0], RMAP_EVENT_PLIST_ADDED);
}
DEFUN (no_match_ip_route_source_prefix_list,
@@ -2686,10 +3223,9 @@ DEFUN (no_match_ip_route_source_prefix_list,
"Match advertising source address of route\n"
"Match entries of prefix-lists\n")
{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
-
- return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list",
+ argc == 0 ? NULL : argv[0],
+ RMAP_EVENT_PLIST_DELETED);
}
ALIAS (no_match_ip_route_source_prefix_list,
@@ -2709,7 +3245,8 @@ DEFUN (match_metric,
"Match metric of route\n"
"Metric value\n")
{
- return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "metric", argv[0],
+ RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_metric,
@@ -2719,10 +3256,9 @@ DEFUN (no_match_metric,
MATCH_STR
"Match metric of route\n")
{
- if (argc == 0)
- return bgp_route_match_delete (vty, vty->index, "metric", NULL);
-
- return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "metric",
+ argc == 0 ? NULL : argv[0],
+ RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_metric,
@@ -2733,6 +3269,40 @@ ALIAS (no_match_metric,
"Match metric of route\n"
"Metric value\n")
+DEFUN (match_local_pref,
+ match_local_pref_cmd,
+ "match local-preference <0-4294967295>",
+ MATCH_STR
+ "Match local-preference of route\n"
+ "Metric value\n")
+{
+ return bgp_route_match_add (vty, vty->index, "local-preference", argv[0],
+ RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFUN (no_match_local_pref,
+ no_match_local_pref_cmd,
+ "no match local-preference",
+ NO_STR
+ MATCH_STR
+ "Match local preference of route\n")
+{
+ return bgp_route_match_delete (vty, vty->index, "local-preference",
+ argc == 0 ? NULL : argv[0],
+ RMAP_EVENT_MATCH_DELETED);
+
+ return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0],
+ RMAP_EVENT_MATCH_DELETED);
+}
+
+ALIAS (no_match_local_pref,
+ no_match_local_pref_val_cmd,
+ "no match local-preference <0-4294967295>",
+ NO_STR
+ MATCH_STR
+ "Match local preference of route\n"
+ "Local preference value\n")
+
DEFUN (match_community,
match_community_cmd,
"match community (<1-99>|<100-500>|WORD)",
@@ -2742,7 +3312,8 @@ DEFUN (match_community,
"Community-list number (expanded)\n"
"Community-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "community", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "community", argv[0],
+ RMAP_EVENT_CLIST_ADDED);
}
DEFUN (match_community_exact,
@@ -2763,7 +3334,8 @@ DEFUN (match_community_exact,
sprintf (argstr, "%s exact-match", argv[0]);
- ret = bgp_route_match_add (vty, vty->index, "community", argstr);
+ ret = bgp_route_match_add (vty, vty->index, "community", argstr,
+ RMAP_EVENT_CLIST_ADDED);
XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
@@ -2777,7 +3349,8 @@ DEFUN (no_match_community,
MATCH_STR
"Match BGP community list\n")
{
- return bgp_route_match_delete (vty, vty->index, "community", NULL);
+ return bgp_route_match_delete (vty, vty->index, "community", NULL,
+ RMAP_EVENT_CLIST_DELETED);
}
ALIAS (no_match_community,
@@ -2810,7 +3383,8 @@ DEFUN (match_ecommunity,
"Extended community-list number (expanded)\n"
"Extended community-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0],
+ RMAP_EVENT_ECLIST_ADDED);
}
DEFUN (no_match_ecommunity,
@@ -2820,7 +3394,8 @@ DEFUN (no_match_ecommunity,
MATCH_STR
"Match BGP/VPN extended community list\n")
{
- return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
+ return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL,
+ RMAP_EVENT_ECLIST_DELETED);
}
ALIAS (no_match_ecommunity,
@@ -2840,7 +3415,8 @@ DEFUN (match_aspath,
"Match BGP AS path list\n"
"AS path access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "as-path", argv[0],
+ RMAP_EVENT_ASLIST_ADDED);
}
DEFUN (no_match_aspath,
@@ -2850,7 +3426,8 @@ DEFUN (no_match_aspath,
MATCH_STR
"Match BGP AS path list\n")
{
- return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
+ return bgp_route_match_delete (vty, vty->index, "as-path", NULL,
+ RMAP_EVENT_ASLIST_DELETED);
}
ALIAS (no_match_aspath,
@@ -2871,11 +3448,14 @@ DEFUN (match_origin,
"unknown heritage\n")
{
if (strncmp (argv[0], "igp", 2) == 0)
- return bgp_route_match_add (vty, vty->index, "origin", "igp");
+ return bgp_route_match_add (vty, vty->index, "origin", "igp",
+ RMAP_EVENT_MATCH_ADDED);
if (strncmp (argv[0], "egp", 1) == 0)
- return bgp_route_match_add (vty, vty->index, "origin", "egp");
+ return bgp_route_match_add (vty, vty->index, "origin", "egp",
+ RMAP_EVENT_MATCH_ADDED);
if (strncmp (argv[0], "incomplete", 2) == 0)
- return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
+ return bgp_route_match_add (vty, vty->index, "origin", "incomplete",
+ RMAP_EVENT_MATCH_ADDED);
return CMD_WARNING;
}
@@ -2887,7 +3467,8 @@ DEFUN (no_match_origin,
MATCH_STR
"BGP origin code\n")
{
- return bgp_route_match_delete (vty, vty->index, "origin", NULL);
+ return bgp_route_match_delete (vty, vty->index, "origin", NULL,
+ RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_origin,
@@ -2900,6 +3481,75 @@ ALIAS (no_match_origin,
"local IGP\n"
"unknown heritage\n")
+DEFUN (match_interface,
+ match_interface_cmd,
+ "match interface WORD",
+ MATCH_STR
+ "Match first hop interface of route\n"
+ "Interface name\n")
+{
+ return bgp_route_match_add (vty, vty->index, "interface", argv[0],
+ RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFUN (no_match_interface,
+ no_match_interface_cmd,
+ "no match interface",
+ NO_STR
+ MATCH_STR
+ "Match first hop interface of route\n")
+{
+ if (argc == 0)
+ return bgp_route_match_delete (vty, vty->index, "interface", NULL,
+ RMAP_EVENT_MATCH_DELETED);
+
+ return bgp_route_match_delete (vty, vty->index, "interface", argv[0],
+ RMAP_EVENT_MATCH_DELETED);
+}
+
+ALIAS (no_match_interface,
+ no_match_interface_val_cmd,
+ "no match interface WORD",
+ NO_STR
+ MATCH_STR
+ "Match first hop interface of route\n"
+ "Interface name\n")
+
+DEFUN (match_tag,
+ match_tag_cmd,
+ "match tag <1-65535>",
+ MATCH_STR
+ "Match tag of route\n"
+ "Tag value\n")
+{
+ return bgp_route_match_add (vty, vty->index, "tag", argv[0],
+ RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFUN (no_match_tag,
+ no_match_tag_cmd,
+ "no match tag",
+ NO_STR
+ MATCH_STR
+ "Match tag of route\n")
+{
+ if (argc == 0)
+ return bgp_route_match_delete (vty, vty->index, "tag", NULL,
+ RMAP_EVENT_MATCH_DELETED);
+
+ return bgp_route_match_delete (vty, vty->index, "tag", argv[0],
+ RMAP_EVENT_MATCH_DELETED);
+}
+
+ALIAS (no_match_tag,
+ no_match_tag_val_cmd,
+ "no match tag <1-65535>",
+ NO_STR
+ MATCH_STR
+ "Match tag of route\n"
+ "Tag value\n")
+
+
DEFUN (set_ip_nexthop,
set_ip_nexthop_cmd,
"set ip next-hop A.B.C.D",
@@ -3313,7 +3963,7 @@ DEFUN (set_community_delete,
SET_STR
"set BGP community list (for deletion)\n"
"Community-list number (standard)\n"
- "Communitly-list number (expanded)\n"
+ "Community-list number (expanded)\n"
"Community-list name\n"
"Delete matching communities\n")
{
@@ -3346,7 +3996,7 @@ ALIAS (no_set_community_delete,
SET_STR
"set BGP community list (for deletion)\n"
"Community-list number (standard)\n"
- "Communitly-list number (expanded)\n"
+ "Community-list number (expanded)\n"
"Community-list name\n"
"Delete matching communities\n")
@@ -3565,6 +4215,38 @@ ALIAS (no_set_aggregator_as,
"AS number\n"
"IP address of aggregator\n")
+DEFUN (set_tag,
+ set_tag_cmd,
+ "set tag <1-65535>",
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+{
+ return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
+}
+
+DEFUN (no_set_tag,
+ no_set_tag_cmd,
+ "no set tag",
+ NO_STR
+ SET_STR
+ "Tag value for routing protocol\n")
+{
+ if (argc == 0)
+ bgp_route_set_delete(vty, vty->index, "tag", NULL);
+
+ return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
+}
+
+ALIAS (no_set_tag,
+ no_set_tag_val_cmd,
+ "no set tag <1-65535>",
+ NO_STR
+ SET_STR
+ "Tag value for routing protocol\n"
+ "Tag value\n")
+
+
DEFUN (match_ipv6_address,
match_ipv6_address_cmd,
"match ipv6 address WORD",
@@ -3573,7 +4255,8 @@ DEFUN (match_ipv6_address,
"Match IPv6 address of route\n"
"IPv6 access-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0],
+ RMAP_EVENT_FILTER_ADDED);
}
DEFUN (no_match_ipv6_address,
@@ -3585,7 +4268,8 @@ DEFUN (no_match_ipv6_address,
"Match IPv6 address of route\n"
"IPv6 access-list name\n")
{
- return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0],
+ RMAP_EVENT_FILTER_DELETED);
}
DEFUN (match_ipv6_next_hop,
@@ -3596,7 +4280,8 @@ DEFUN (match_ipv6_next_hop,
"Match IPv6 next-hop address of route\n"
"IPv6 address of next hop\n")
{
- return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0],
+ RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_ipv6_next_hop,
@@ -3608,7 +4293,8 @@ DEFUN (no_match_ipv6_next_hop,
"Match IPv6 next-hop address of route\n"
"IPv6 address of next hop\n")
{
- return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0],
+ RMAP_EVENT_MATCH_DELETED);
}
DEFUN (match_ipv6_address_prefix_list,
@@ -3620,7 +4306,8 @@ DEFUN (match_ipv6_address_prefix_list,
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
- return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
+ return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list",
+ argv[0], RMAP_EVENT_PLIST_ADDED);
}
DEFUN (no_match_ipv6_address_prefix_list,
@@ -3633,7 +4320,8 @@ DEFUN (no_match_ipv6_address_prefix_list,
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
- return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
+ return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list",
+ argv[0], RMAP_EVENT_PLIST_DELETED);
}
DEFUN (set_ipv6_nexthop_peer,
@@ -3863,10 +4551,12 @@ bgp_route_map_init (void)
{
route_map_init ();
route_map_init_vty ();
- route_map_add_hook (bgp_route_map_update);
- route_map_delete_hook (bgp_route_map_update);
+ route_map_add_hook (bgp_route_map_add);
+ route_map_delete_hook (bgp_route_map_delete);
+ route_map_event_hook (bgp_route_map_event);
route_map_install_match (&route_match_peer_cmd);
+ route_map_install_match (&route_match_local_pref_cmd);
route_map_install_match (&route_match_ip_address_cmd);
route_map_install_match (&route_match_ip_next_hop_cmd);
route_map_install_match (&route_match_ip_route_source_cmd);
@@ -3876,9 +4566,12 @@ bgp_route_map_init (void)
route_map_install_match (&route_match_aspath_cmd);
route_map_install_match (&route_match_community_cmd);
route_map_install_match (&route_match_ecommunity_cmd);
+ route_map_install_match (&route_match_local_pref_cmd);
route_map_install_match (&route_match_metric_cmd);
route_map_install_match (&route_match_origin_cmd);
route_map_install_match (&route_match_probability_cmd);
+ route_map_install_match (&route_match_interface_cmd);
+ route_map_install_match (&route_match_tag_cmd);
route_map_install_set (&route_set_ip_nexthop_cmd);
route_map_install_set (&route_set_local_pref_cmd);
@@ -3895,6 +4588,7 @@ bgp_route_map_init (void)
route_map_install_set (&route_set_originator_id_cmd);
route_map_install_set (&route_set_ecommunity_rt_cmd);
route_map_install_set (&route_set_ecommunity_soo_cmd);
+ route_map_install_set (&route_set_tag_cmd);
install_element (RMAP_NODE, &match_peer_cmd);
install_element (RMAP_NODE, &match_peer_local_cmd);
@@ -3926,6 +4620,9 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &match_metric_cmd);
install_element (RMAP_NODE, &no_match_metric_cmd);
install_element (RMAP_NODE, &no_match_metric_val_cmd);
+ install_element (RMAP_NODE, &match_local_pref_cmd);
+ install_element (RMAP_NODE, &no_match_local_pref_cmd);
+ install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
install_element (RMAP_NODE, &match_community_cmd);
install_element (RMAP_NODE, &match_community_exact_cmd);
install_element (RMAP_NODE, &no_match_community_cmd);
@@ -3940,6 +4637,12 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &match_probability_cmd);
install_element (RMAP_NODE, &no_match_probability_cmd);
install_element (RMAP_NODE, &no_match_probability_val_cmd);
+ install_element (RMAP_NODE, &match_interface_cmd);
+ install_element (RMAP_NODE, &no_match_interface_cmd);
+ install_element (RMAP_NODE, &no_match_interface_val_cmd);
+ install_element (RMAP_NODE, &match_tag_cmd);
+ install_element (RMAP_NODE, &no_match_tag_cmd);
+ install_element (RMAP_NODE, &no_match_tag_val_cmd);
install_element (RMAP_NODE, &set_ip_nexthop_cmd);
install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
@@ -3991,6 +4694,9 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &set_originator_id_cmd);
install_element (RMAP_NODE, &no_set_originator_id_cmd);
install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
+ install_element (RMAP_NODE, &set_tag_cmd);
+ install_element (RMAP_NODE, &no_set_tag_cmd);
+ install_element (RMAP_NODE, &no_set_tag_val_cmd);
route_map_install_match (&route_match_ipv6_address_cmd);
route_map_install_match (&route_match_ipv6_next_hop_cmd);
@@ -4024,3 +4730,15 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
}
+
+void
+bgp_route_map_terminate (void)
+{
+ /* ToDo: Cleanup all the used memory */
+
+ route_map_add_hook (NULL);
+ route_map_delete_hook (NULL);
+ route_map_event_hook (NULL);
+ route_map_finish();
+
+}