aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2021-05-07 20:36:50 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2021-05-30 10:30:45 +0000
commitf279295521400a36626ea367e83e432f5e99238f (patch)
treefda1559c8801a83f168d2ca9d4aec322fbb8a3af
parent2e170ce65b10e4a06345df561535677413bb723c (diff)
downloadsrc-f279295521400a36626ea367e83e432f5e99238f.tar.gz
src-f279295521400a36626ea367e83e432f5e99238f.zip
Fix panic when trying to delete non-existent gateway in multipath route.
IF non-existend gateway was specified, the code responsible for calculating an updated nexthop group, returned the same already-used nexthop group. After the route table update, the operation result contained the same old & new nexthop groups. Thus, the code responsible for decomposing the notification to the list of simple nexthop-level notifications, was not able to find any differences. As a result, it hasn't updated any of the "simple" notification fields, resulting in empty rtentry pointer. This empty pointer was the direct reason of a panic. Fix the problem by returning ESRCH when the new nexthop group is the same as the old one after applying gateway filter. Reported by: Michael <michael.adm at gmail.com> PR: 255665
-rw-r--r--sys/net/route/mpath_ctl.c11
-rw-r--r--sys/net/route/nhgrp_ctl.c6
2 files changed, 11 insertions, 6 deletions
diff --git a/sys/net/route/mpath_ctl.c b/sys/net/route/mpath_ctl.c
index 5632750f466d..8351437e34c6 100644
--- a/sys/net/route/mpath_ctl.c
+++ b/sys/net/route/mpath_ctl.c
@@ -181,10 +181,15 @@ del_route_mpath(struct rib_head *rh, struct rt_addrinfo *info,
if ((info->rti_info[RTAX_GATEWAY] == NULL) && (info->rti_filter == NULL))
return (ESRCH);
- error = nhgrp_get_filtered_group(rh, nhg, gw_filter_func, (void *)&ri,
- &rnd);
- if (error == 0)
+ error = nhgrp_get_filtered_group(rh, nhg, gw_filter_func, (void *)&ri, &rnd);
+ if (error == 0) {
+ if (rnd.rnd_nhgrp == nhg) {
+ /* No gateway match, unreference new group and return. */
+ nhop_free_any(rnd.rnd_nhop);
+ return (ESRCH);
+ }
error = change_route_nhop(rh, rt, info, &rnd, rc);
+ }
return (error);
}
diff --git a/sys/net/route/nhgrp_ctl.c b/sys/net/route/nhgrp_ctl.c
index 49866499ac86..9f1f3a5b4bc4 100644
--- a/sys/net/route/nhgrp_ctl.c
+++ b/sys/net/route/nhgrp_ctl.c
@@ -578,9 +578,9 @@ nhgrp_get_group(struct rib_head *rh, struct weightened_nhop *wn, int num_nhops,
}
/*
- * Creates new nexthop group based on @src group with the nexthops defined in bitmask
- * @nhop_mask removed.
- * Returns referenced nexthop group or NULL on failure.
+ * Creates new nexthop group based on @src group without the nexthops
+ * chosen by @flt_func.
+ * Returns 0 on success, storring the reference nhop group/object in @rnd.
*/
int
nhgrp_get_filtered_group(struct rib_head *rh, const struct nhgrp_object *src,