浏览代码

ip_tunnel: Fix dst ref-count.

Commit 10ddceb22ba (ip_tunnel:multicast process cause panic due
to skb->_skb_refdst NULL pointer) removed dst-drop call from
ip-tunnel-recv.

Following commit reintroduce dst-drop and fix the original bug by
checking loopback packet before releasing dst.
Original bug: https://bugzilla.kernel.org/show_bug.cgi?id=70681

CC: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Pravin B Shelar 11 年之前
父节点
当前提交
fbd02dd405
共有 3 个文件被更改,包括 9 次插入3 次删除
  1. 8 0
      net/ipv4/gre_demux.c
  2. 0 3
      net/ipv4/ip_tunnel.c
  3. 1 0
      net/ipv4/ip_tunnel_core.c

+ 8 - 0
net/ipv4/gre_demux.c

@@ -182,6 +182,14 @@ static int gre_cisco_rcv(struct sk_buff *skb)
 	int i;
 	int i;
 	bool csum_err = false;
 	bool csum_err = false;
 
 
+#ifdef CONFIG_NET_IPGRE_BROADCAST
+	if (ipv4_is_multicast(ip_hdr(skb)->daddr)) {
+		/* Looped back packet, drop it! */
+		if (rt_is_output_route(skb_rtable(skb)))
+			goto drop;
+	}
+#endif
+
 	if (parse_gre_header(skb, &tpi, &csum_err) < 0)
 	if (parse_gre_header(skb, &tpi, &csum_err) < 0)
 		goto drop;
 		goto drop;
 
 

+ 0 - 3
net/ipv4/ip_tunnel.c

@@ -416,9 +416,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
 
 
 #ifdef CONFIG_NET_IPGRE_BROADCAST
 #ifdef CONFIG_NET_IPGRE_BROADCAST
 	if (ipv4_is_multicast(iph->daddr)) {
 	if (ipv4_is_multicast(iph->daddr)) {
-		/* Looped back packet, drop it! */
-		if (rt_is_output_route(skb_rtable(skb)))
-			goto drop;
 		tunnel->dev->stats.multicast++;
 		tunnel->dev->stats.multicast++;
 		skb->pkt_type = PACKET_BROADCAST;
 		skb->pkt_type = PACKET_BROADCAST;
 	}
 	}

+ 1 - 0
net/ipv4/ip_tunnel_core.c

@@ -108,6 +108,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
 	nf_reset(skb);
 	nf_reset(skb);
 	secpath_reset(skb);
 	secpath_reset(skb);
 	skb_clear_hash_if_not_l4(skb);
 	skb_clear_hash_if_not_l4(skb);
+	skb_dst_drop(skb);
 	skb->vlan_tci = 0;
 	skb->vlan_tci = 0;
 	skb_set_queue_mapping(skb, 0);
 	skb_set_queue_mapping(skb, 0);
 	skb->pkt_type = PACKET_HOST;
 	skb->pkt_type = PACKET_HOST;