diff options
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
| -rw-r--r-- | net/ipv6/ipv6_sockglue.c | 61 | 
1 files changed, 60 insertions, 1 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1160400e9db..bd43f0152c2 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -337,6 +337,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,  		retv = 0;  		break; +	case IPV6_RECVPATHMTU: +		if (optlen < sizeof(int)) +			goto e_inval; +		np->rxopt.bits.rxpmtu = valbool; +		retv = 0; +		break; +  	case IPV6_HOPOPTS:  	case IPV6_RTHDRDSTOPTS:  	case IPV6_RTHDR: @@ -451,7 +458,8 @@ sticky_done:  		msg.msg_controllen = optlen;  		msg.msg_control = (void*)(opt+1); -		retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk); +		retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk, +					 &junk);  		if (retv)  			goto done;  update: @@ -767,6 +775,17 @@ pref_skip_coa:  		break;  	    } +	case IPV6_MINHOPCOUNT: +		if (optlen < sizeof(int)) +			goto e_inval; +		if (val < 0 || val > 255) +			goto e_inval; +		np->min_hopcount = val; +		break; +	case IPV6_DONTFRAG: +		np->dontfrag = valbool; +		retv = 0; +		break;  	}  	release_sock(sk); @@ -1055,6 +1074,38 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,  		val = np->rxopt.bits.rxflow;  		break; +	case IPV6_RECVPATHMTU: +		val = np->rxopt.bits.rxpmtu; +		break; + +	case IPV6_PATHMTU: +	{ +		struct dst_entry *dst; +		struct ip6_mtuinfo mtuinfo; + +		if (len < sizeof(mtuinfo)) +			return -EINVAL; + +		len = sizeof(mtuinfo); +		memset(&mtuinfo, 0, sizeof(mtuinfo)); + +		rcu_read_lock(); +		dst = __sk_dst_get(sk); +		if (dst) +			mtuinfo.ip6m_mtu = dst_mtu(dst); +		rcu_read_unlock(); +		if (!mtuinfo.ip6m_mtu) +			return -ENOTCONN; + +		if (put_user(len, optlen)) +			return -EFAULT; +		if (copy_to_user(optval, &mtuinfo, len)) +			return -EFAULT; + +		return 0; +		break; +	} +  	case IPV6_UNICAST_HOPS:  	case IPV6_MULTICAST_HOPS:  	{ @@ -1116,6 +1167,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,  			val |= IPV6_PREFER_SRC_HOME;  		break; +	case IPV6_MINHOPCOUNT: +		val = np->min_hopcount; +		break; + +	case IPV6_DONTFRAG: +		val = np->dontfrag; +		break; +  	default:  		return -ENOPROTOOPT;  	}  |