summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-08-22 13:50:14 +0200
committerGitHub <noreply@github.com>2018-08-22 13:50:14 +0200
commitdca5ef30533ab2a7a5573f065537e7a05067bec7 (patch)
treecabdc1fc450c57f56ede9d7e8ab6110334b2d01f /zebra
parentMerge pull request #2888 from pguibert6WIND/misc_fix_static_tableid (diff)
parentzebra : routemap "match ipv6 address prefix list" does not work (diff)
downloadfrr-dca5ef30533ab2a7a5573f065537e7a05067bec7.tar.xz
frr-dca5ef30533ab2a7a5573f065537e7a05067bec7.zip
Merge pull request #2818 from kssoman/rmap_fix
Zebra does not properly track which route-maps are changed (#2493)
Diffstat (limited to 'zebra')
-rw-r--r--zebra/redistribute.c7
-rw-r--r--zebra/redistribute.h3
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/zebra_rib.c13
-rw-r--r--zebra/zebra_routemap.c136
5 files changed, 139 insertions, 22 deletions
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index e3101fbe7..640d58e17 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -715,7 +715,7 @@ int zebra_import_table_config(struct vty *vty)
return write;
}
-void zebra_import_table_rm_update()
+void zebra_import_table_rm_update(const char *rmap)
{
afi_t afi;
int i;
@@ -730,9 +730,8 @@ void zebra_import_table_rm_update()
continue;
rmap_name = zebra_get_import_table_route_map(afi, i);
- if (!rmap_name)
- return;
-
+ if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
+ continue;
table = zebra_vrf_other_route_table(afi, i,
VRF_DEFAULT);
for (rn = route_top(table); rn; rn = route_next(rn)) {
diff --git a/zebra/redistribute.h b/zebra/redistribute.h
index a0fbd13cf..f67480da9 100644
--- a/zebra/redistribute.h
+++ b/zebra/redistribute.h
@@ -71,6 +71,5 @@ extern int is_zebra_import_table_enabled(afi_t, uint32_t table_id);
extern int zebra_import_table_config(struct vty *);
-extern void zebra_import_table_rm_update(void);
-
+extern void zebra_import_table_rm_update(const char *rmap);
#endif /* _ZEBRA_REDISTRIBUTE_H */
diff --git a/zebra/rib.h b/zebra/rib.h
index a37b2bf22..f821c6edb 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -325,6 +325,8 @@ extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p,
vrf_id_t vrf_id);
extern void rib_update(vrf_id_t vrf_id, rib_update_event_t event);
+extern void rib_update_table(struct route_table *table,
+ rib_update_event_t event);
extern void rib_sweep_route(void);
extern void rib_sweep_table(struct route_table *table);
extern void rib_close_table(struct route_table *table);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b477cd470..99b83d5cd 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2651,8 +2651,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
}
/* Schedule routes of a particular table (address-family) based on event. */
-static void rib_update_table(struct route_table *table,
- rib_update_event_t event)
+void rib_update_table(struct route_table *table, rib_update_event_t event)
{
struct route_node *rn;
struct route_entry *re, *next;
@@ -2732,12 +2731,18 @@ void rib_update(vrf_id_t vrf_id, rib_update_event_t event)
/* Process routes of interested address-families. */
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
- if (table)
+ if (table) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP event %d", __func__, event);
rib_update_table(table, event);
+ }
table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
- if (table)
+ if (table) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP6 event %d", __func__, event);
rib_update_table(table, event);
+ }
}
/* Delete self installed routes after zebra is relaunched. */
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index fc17ee349..7a6bc6684 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -1033,13 +1033,13 @@ static struct route_map_rule_cmd route_match_ip_address_cmd = {
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
- route_map_object_t type, void *object)
+route_match_address_prefix_list(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object, afi_t afi)
{
struct prefix_list *plist;
if (type == RMAP_ZEBRA) {
- plist = prefix_list_lookup(AFI_IP, (char *)rule);
+ plist = prefix_list_lookup(afi, (char *)rule);
if (plist == NULL)
return RMAP_NOMATCH;
@@ -1050,21 +1050,41 @@ route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
return RMAP_NOMATCH;
}
-static void *route_match_ip_address_prefix_list_compile(const char *arg)
+static route_map_result_t
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ return (route_match_address_prefix_list(rule, prefix, type, object,
+ AFI_IP));
+}
+
+static void *route_match_address_prefix_list_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
-static void route_match_ip_address_prefix_list_free(void *rule)
+static void route_match_address_prefix_list_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
"ip address prefix-list", route_match_ip_address_prefix_list,
- route_match_ip_address_prefix_list_compile,
- route_match_ip_address_prefix_list_free};
+ route_match_address_prefix_list_compile,
+ route_match_address_prefix_list_free};
+static route_map_result_t
+route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ return (route_match_address_prefix_list(rule, prefix, type, object,
+ AFI_IP6));
+}
+
+static struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
+ "ipv6 address prefix-list", route_match_ipv6_address_prefix_list,
+ route_match_address_prefix_list_compile,
+ route_match_address_prefix_list_free};
/* `match ip address prefix-len PREFIXLEN' */
@@ -1281,11 +1301,101 @@ static struct route_map_rule_cmd route_set_src_cmd = {
"src", route_set_src, route_set_src_compile, route_set_src_free,
};
+/* The function checks if the changed routemap specified by parameter rmap
+ * matches the configured protocol routemaps in proto_rm table. If there is
+ * a match then rib_update_table() to process the routes.
+ */
+static void zebra_rib_table_rm_update(const char *rmap)
+{
+ int i = 0;
+ struct route_table *table;
+ char *rmap_name;
+ char afi_ip = 0;
+ char afi_ipv6 = 0;
+
+ for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
+ /* Check for ip routemap table */
+ rmap_name = proto_rm[AFI_IP][i];
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP rmap %s, route type %s",
+ __func__, rmap, zebra_route_string(i));
+ /* There is single rib table for all protocols */
+ if (afi_ip == 0) {
+ table = zebra_vrf_table(AFI_IP, SAFI_UNICAST,
+ VRF_DEFAULT);
+ if (table) {
+ afi_ip = 1;
+ rib_update_table(table,
+ RIB_UPDATE_RMAP_CHANGE);
+ }
+ }
+ }
+
+ /* Check for ipv6 routemap table */
+ rmap_name = proto_rm[AFI_IP6][i];
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP6 rmap %s,route type %s",
+ __func__, rmap, zebra_route_string(i));
+ if (afi_ipv6 == 0) {
+ table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST,
+ VRF_DEFAULT);
+ if (table) {
+ afi_ipv6 = 1;
+ rib_update_table(table,
+ RIB_UPDATE_RMAP_CHANGE);
+ }
+ }
+ }
+ }
+}
+
+/* The function checks if the changed routemap specified by parameter rmap
+ * matches the configured protocol routemaps in nht_rm table. If there is
+ * a match then zebra_evaluate_rnh() to process the nexthops.
+ */
+static void zebra_nht_rm_update(const char *rmap)
+{
+ int i = 0;
+ char *rmap_name;
+ char afi_ip = 0;
+ char afi_ipv6 = 0;
+
+ for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
+ rmap_name = nht_rm[AFI_IP][i];
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP rmap %s route type %s",
+ __func__, rmap, zebra_route_string(i));
+ if (afi_ip == 0) {
+ afi_ip = 1;
+ zebra_evaluate_rnh(0, AF_INET, 1,
+ RNH_NEXTHOP_TYPE, NULL);
+ }
+ }
+ rmap_name = nht_rm[AFI_IP6][i];
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP6 rmap %s route type %s",
+ __func__, rmap, zebra_route_string(i));
+ if (afi_ipv6 == 0) {
+ afi_ipv6 = 1;
+ zebra_evaluate_rnh(0, AF_INET6, 1,
+ RNH_NEXTHOP_TYPE, NULL);
+ }
+ }
+ }
+}
+
static void zebra_route_map_process_update_cb(char *rmap_name)
{
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("Event handler for route-map: %s",
rmap_name);
+ zebra_import_table_rm_update(rmap_name);
+ zebra_rib_table_rm_update(rmap_name);
+ zebra_nht_rm_update(rmap_name);
}
static int zebra_route_map_update_timer(struct thread *thread)
@@ -1307,11 +1417,6 @@ static int zebra_route_map_update_timer(struct thread *thread)
* 1) VRF Aware <sigh>
* 2) Route-map aware
*/
- zebra_import_table_rm_update();
- rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
- zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
- zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
-
return (0);
}
@@ -1555,12 +1660,19 @@ void zebra_route_map_init()
route_map_match_tag_hook(generic_match_add);
route_map_no_match_tag_hook(generic_match_delete);
+ route_map_match_ipv6_address_hook(generic_match_add);
+ route_map_no_match_ipv6_address_hook(generic_match_delete);
+
+ route_map_match_ipv6_address_prefix_list_hook(generic_match_add);
+ route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete);
+
route_map_install_match(&route_match_tag_cmd);
route_map_install_match(&route_match_interface_cmd);
route_map_install_match(&route_match_ip_next_hop_cmd);
route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
route_map_install_match(&route_match_ip_address_cmd);
route_map_install_match(&route_match_ip_address_prefix_list_cmd);
+ route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
route_map_install_match(&route_match_ip_address_prefix_len_cmd);
route_map_install_match(&route_match_ipv6_address_prefix_len_cmd);
route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd);