File tree Expand file tree Collapse file tree 1 file changed +12
-2
lines changed Expand file tree Collapse file tree 1 file changed +12
-2
lines changed Original file line number Diff line number Diff line change @@ -262,10 +262,18 @@ static int rpl_input(struct sk_buff *skb)
262
262
{
263
263
struct dst_entry * orig_dst = skb_dst (skb );
264
264
struct dst_entry * dst = NULL ;
265
+ struct lwtunnel_state * lwtst ;
265
266
struct rpl_lwt * rlwt ;
266
267
int err ;
267
268
268
- rlwt = rpl_lwt_lwtunnel (orig_dst -> lwtstate );
269
+ /* We cannot dereference "orig_dst" once ip6_route_input() or
270
+ * skb_dst_drop() is called. However, in order to detect a dst loop, we
271
+ * need the address of its lwtstate. So, save the address of lwtstate
272
+ * now and use it later as a comparison.
273
+ */
274
+ lwtst = orig_dst -> lwtstate ;
275
+
276
+ rlwt = rpl_lwt_lwtunnel (lwtst );
269
277
270
278
local_bh_disable ();
271
279
dst = dst_cache_get (& rlwt -> cache );
@@ -280,7 +288,9 @@ static int rpl_input(struct sk_buff *skb)
280
288
if (!dst ) {
281
289
ip6_route_input (skb );
282
290
dst = skb_dst (skb );
283
- if (!dst -> error ) {
291
+
292
+ /* cache only if we don't create a dst reference loop */
293
+ if (!dst -> error && lwtst != dst -> lwtstate ) {
284
294
local_bh_disable ();
285
295
dst_cache_set_ip6 (& rlwt -> cache , dst ,
286
296
& ipv6_hdr (skb )-> saddr );
You can’t perform that action at this time.
0 commit comments