diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/ip6_fib.c | 28 | ||||
| -rw-r--r-- | net/ipv6/route.c | 19 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 4 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 3 | 
4 files changed, 27 insertions, 27 deletions
| diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ebb299cf72b7..5cc0ea038198 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -914,6 +914,8 @@ add:  		}  		nsiblings = iter->rt6i_nsiblings;  		fib6_purge_rt(iter, fn, info->nl_net); +		if (fn->rr_ptr == iter) +			fn->rr_ptr = NULL;  		rt6_release(iter);  		if (nsiblings) { @@ -926,6 +928,8 @@ add:  				if (rt6_qualify_for_ecmp(iter)) {  					*ins = iter->dst.rt6_next;  					fib6_purge_rt(iter, fn, info->nl_net); +					if (fn->rr_ptr == iter) +						fn->rr_ptr = NULL;  					rt6_release(iter);  					nsiblings--;  				} else { @@ -1014,7 +1018,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,  			/* Create subtree root node */  			sfn = node_alloc();  			if (!sfn) -				goto st_failure; +				goto failure;  			sfn->leaf = info->nl_net->ipv6.ip6_null_entry;  			atomic_inc(&info->nl_net->ipv6.ip6_null_entry->rt6i_ref); @@ -1031,12 +1035,12 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,  			if (IS_ERR(sn)) {  				/* If it is failed, discard just allocated -				   root, and then (in st_failure) stale node +				   root, and then (in failure) stale node  				   in main tree.  				 */  				node_free(sfn);  				err = PTR_ERR(sn); -				goto st_failure; +				goto failure;  			}  			/* Now link new subtree to main tree */ @@ -1051,7 +1055,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,  			if (IS_ERR(sn)) {  				err = PTR_ERR(sn); -				goto st_failure; +				goto failure;  			}  		} @@ -1092,18 +1096,17 @@ out:  			atomic_inc(&pn->leaf->rt6i_ref);  		}  #endif -		/* Always release dst as dst->__refcnt is guaranteed -		 * to be taken before entering this function -		 */ -		dst_release_immediate(&rt->dst); +		goto failure;  	}  	return err; -#ifdef CONFIG_IPV6_SUBTREES -	/* Subtree creation failed, probably main tree node -	   is orphan. If it is, shoot it. +failure: +	/* fn->leaf could be NULL if fn is an intermediate node and we +	 * failed to add the new route to it in both subtree creation +	 * failure and fib6_add_rt2node() failure case. +	 * In both cases, fib6_repair_tree() should be called to fix +	 * fn->leaf.  	 */ -st_failure:  	if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)))  		fib6_repair_tree(info->nl_net, fn);  	/* Always release dst as dst->__refcnt is guaranteed @@ -1111,7 +1114,6 @@ st_failure:  	 */  	dst_release_immediate(&rt->dst);  	return err; -#endif  }  /* diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a640fbcba15d..94d6a13d47f0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -417,14 +417,11 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,  	struct net_device *loopback_dev =  		dev_net(dev)->loopback_dev; -	if (dev != loopback_dev) { -		if (idev && idev->dev == dev) { -			struct inet6_dev *loopback_idev = -				in6_dev_get(loopback_dev); -			if (loopback_idev) { -				rt->rt6i_idev = loopback_idev; -				in6_dev_put(idev); -			} +	if (idev && idev->dev != loopback_dev) { +		struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); +		if (loopback_idev) { +			rt->rt6i_idev = loopback_idev; +			in6_dev_put(idev);  		}  	}  } @@ -3724,10 +3721,10 @@ static int ip6_route_dev_notify(struct notifier_block *this,  		/* NETDEV_UNREGISTER could be fired for multiple times by  		 * netdev_wait_allrefs(). Make sure we only call this once.  		 */ -		in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev); +		in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);  #ifdef CONFIG_IPV6_MULTIPLE_TABLES -		in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev); -		in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev); +		in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); +		in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);  #endif  	} diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2521690d62d6..206210125fd7 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1456,6 +1456,8 @@ process:  		}  		sock_hold(sk);  		refcounted = true; +		if (tcp_filter(sk, skb)) +			goto discard_and_relse;  		nsk = tcp_check_req(sk, skb, req, false);  		if (!nsk) {  			reqsk_put(req); @@ -1464,8 +1466,6 @@ process:  		if (nsk == sk) {  			reqsk_put(req);  			tcp_v6_restore_cb(skb); -		} else if (tcp_filter(sk, skb)) { -			goto discard_and_relse;  		} else if (tcp_child_process(sk, nsk, skb)) {  			tcp_v6_send_reset(nsk, skb);  			goto discard_and_relse; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 578142b7ca3e..20039c8501eb 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -362,7 +362,8 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,  		return ipv6_recv_rxpmtu(sk, msg, len, addr_len);  try_again: -	peeking = off = sk_peek_offset(sk, flags); +	peeking = flags & MSG_PEEK; +	off = sk_peek_offset(sk, flags);  	skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);  	if (!skb)  		return err; |