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)
262262{
263263 struct dst_entry * orig_dst = skb_dst (skb );
264264 struct dst_entry * dst = NULL ;
265+ struct lwtunnel_state * lwtst ;
265266 struct rpl_lwt * rlwt ;
266267 int err ;
267268
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 );
269277
270278 local_bh_disable ();
271279 dst = dst_cache_get (& rlwt -> cache );
@@ -280,7 +288,9 @@ static int rpl_input(struct sk_buff *skb)
280288 if (!dst ) {
281289 ip6_route_input (skb );
282290 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 ) {
284294 local_bh_disable ();
285295 dst_cache_set_ip6 (& rlwt -> cache , dst ,
286296 & ipv6_hdr (skb )-> saddr );
You can’t perform that action at this time.
0 commit comments