In shared mode, bwlim_set_limit() stores the stick-table entry returned
by stktable_get_entry(), which takes a reference, into st->ts without
releasing any entry already stored there. When set-bandwidth-limit is
executed more than once for the same stream and shared filter, the
intermediate reference is leaked: bwlim_detach() only releases the last
one. The entry then stays pinned (ref_cnt > 0) and can never be purged,
and with distinct keys the table fills up until the features depending
on it are denied service.
Release the previously held entry before overwriting st->ts.
This was introduced in 2.7 by commit
2b6777021 ("MEDIUM: bwlim: Add
support of bandwith limitation at the stream level") and must be
backported to all stable branches.
Many thanks to Red Hat and AISLE Research for reporting the issue and
providing a fix.
if (!ts)
goto end;
+ /* release any entry held by a previous execution of the action
+ * on the same stream, otherwise its reference would be leaked.
+ */
+ if (st->ts)
+ stktable_touch_local(t, st->ts, 1);
st->ts = ts;
st->rule = rule;
}