summaryrefslogtreecommitdiffstats
path: root/ripngd/ripngd.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2019-01-04 22:08:10 +0100
committerRenato Westphal <renato@opensourcerouting.org>2019-01-18 19:15:41 +0100
commitf9120f719ac2433dd9f168eed97e7b71ea38125e (patch)
tree63a1bfe594d65af6fdcfa3dbe16a7d3445b8b012 /ripngd/ripngd.c
parentripd: fix unsetting of authentication password (diff)
downloadfrr-f9120f719ac2433dd9f168eed97e7b71ea38125e.tar.xz
frr-f9120f719ac2433dd9f168eed97e7b71ea38125e.zip
ripd, ripngd: change how we keep track of redistribution configuration
ripd and ripngd were leveraging the zclient code to keep track of the redistribute configuration, which is what most daemons do. The problem, however, is that the zclient code uses VRF IDs to identify VRFs, and VRF IDs are unknown until a VRF is enabled (information received from zebra). This means we can't configure a redistribute command on a RIP instance when the corresponding VRF is disabled (doing so leads to a null-dereference crash right now in both ripd and ripngd). To fix this, change the rip/ripng data structures so that they keep track of the full redistribute configuration and not only the route-map and metric associated to each command. This is similar to what bgpd and ospfd are doing to solve the same problem. In the future the zclient code and all daemons need to be refactored to consolidate the handling of redistribute configuration in a single place to reduce code duplication. One of the most important changes to do is to use VRF names and not VRF IDs to identify VRFs. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'ripngd/ripngd.c')
-rw-r--r--ripngd/ripngd.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 951c73bc4..c3aa9d8db 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -1682,10 +1682,11 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
}
/* Redistribute route-map. */
- if (ripng->route_map[rinfo->type].name) {
- ret = route_map_apply(
- ripng->route_map[rinfo->type].map,
- (struct prefix *)p, RMAP_RIPNG, rinfo);
+ if (ripng->redist[rinfo->type].route_map.name) {
+ ret = route_map_apply(ripng->redist[rinfo->type]
+ .route_map.map,
+ (struct prefix *)p,
+ RMAP_RIPNG, rinfo);
if (ret == RMAP_DENYMATCH) {
if (IS_RIPNG_DEBUG_PACKET)
@@ -1700,10 +1701,10 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
/* When the route-map does not set metric. */
if (!rinfo->metric_set) {
/* If the redistribute metric is set. */
- if (ripng->route_map[rinfo->type].metric_config
+ if (ripng->redist[rinfo->type].metric_config
&& rinfo->metric != RIPNG_METRIC_INFINITY) {
rinfo->metric_out =
- ripng->route_map[rinfo->type]
+ ripng->redist[rinfo->type]
.metric;
} else {
/* If the route is not connected or
@@ -2531,8 +2532,8 @@ void ripng_clean(struct ripng *ripng)
ripng_instance_disable(ripng);
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++)
- if (ripng->route_map[i].name)
- free(ripng->route_map[i].name);
+ if (ripng->redist[i].route_map.name)
+ free(ripng->redist[i].route_map.name);
agg_table_finish(ripng->table);
list_delete(&ripng->peer_list);
@@ -2548,7 +2549,6 @@ void ripng_clean(struct ripng *ripng)
vector_free(ripng->passive_interface);
list_delete(&ripng->offset_list_master);
ripng_interface_clean(ripng);
- ripng_redistribute_clean(ripng);
RB_REMOVE(ripng_instance_head, &ripng_instances, ripng);
XFREE(MTYPE_RIPNG_VRF_NAME, ripng->vrf_name);
@@ -2598,9 +2598,10 @@ void ripng_if_rmap_update_interface(struct interface *ifp)
static void ripng_routemap_update_redistribute(struct ripng *ripng)
{
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (ripng->route_map[i].name)
- ripng->route_map[i].map = route_map_lookup_by_name(
- ripng->route_map[i].name);
+ if (ripng->redist[i].route_map.name)
+ ripng->redist[i].route_map.map =
+ route_map_lookup_by_name(
+ ripng->redist[i].route_map.name);
}
}
@@ -2652,6 +2653,9 @@ static void ripng_instance_enable(struct ripng *ripng, struct vrf *vrf,
ripng_vrf_link(ripng, vrf);
ripng->enabled = true;
+ /* Resend all redistribute requests. */
+ ripng_redistribute_enable(ripng);
+
/* Create read and timer thread. */
ripng_event(ripng, RIPNG_READ, ripng->sock);
ripng_event(ripng, RIPNG_UPDATE_EVENT, 1);
@@ -2694,6 +2698,9 @@ static void ripng_instance_disable(struct ripng *ripng)
}
}
+ /* Flush all redistribute requests. */
+ ripng_redistribute_disable(ripng);
+
/* Cancel the RIPng timers */
RIPNG_TIMER_OFF(ripng->t_update);
RIPNG_TIMER_OFF(ripng->t_triggered_update);