IPv6: data structure changes for new socket options
Add underlying data structure changes and basic setsockopt() and getsockopt() support for IPV6_RECVPATHMTU, IPV6_PATHMTU, and IPV6_DONTFRAG. IPV6_PATHMTU is actually fully functional at this point. Signed-off-by: Brian Haley <brian.haley@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
3a73702863
commit
793b147316
@@ -221,10 +221,10 @@ struct in6_flowlabel_req {
|
|||||||
#define IPV6_RTHDR 57
|
#define IPV6_RTHDR 57
|
||||||
#define IPV6_RECVDSTOPTS 58
|
#define IPV6_RECVDSTOPTS 58
|
||||||
#define IPV6_DSTOPTS 59
|
#define IPV6_DSTOPTS 59
|
||||||
#if 0 /* not yet */
|
|
||||||
#define IPV6_RECVPATHMTU 60
|
#define IPV6_RECVPATHMTU 60
|
||||||
#define IPV6_PATHMTU 61
|
#define IPV6_PATHMTU 61
|
||||||
#define IPV6_DONTFRAG 62
|
#define IPV6_DONTFRAG 62
|
||||||
|
#if 0 /* not yet */
|
||||||
#define IPV6_USE_MIN_MTU 63
|
#define IPV6_USE_MIN_MTU 63
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -21,6 +21,10 @@ struct in6_pktinfo {
|
|||||||
int ipi6_ifindex;
|
int ipi6_ifindex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ip6_mtuinfo {
|
||||||
|
struct sockaddr_in6 ip6m_addr;
|
||||||
|
__u32 ip6m_mtu;
|
||||||
|
};
|
||||||
|
|
||||||
struct in6_ifreq {
|
struct in6_ifreq {
|
||||||
struct in6_addr ifr6_addr;
|
struct in6_addr ifr6_addr;
|
||||||
@@ -334,22 +338,25 @@ struct ipv6_pinfo {
|
|||||||
dstopts:1,
|
dstopts:1,
|
||||||
odstopts:1,
|
odstopts:1,
|
||||||
rxflow:1,
|
rxflow:1,
|
||||||
rxtclass:1;
|
rxtclass:1,
|
||||||
|
rxpmtu:1;
|
||||||
} bits;
|
} bits;
|
||||||
__u16 all;
|
__u16 all;
|
||||||
} rxopt;
|
} rxopt;
|
||||||
|
|
||||||
/* sockopt flags */
|
/* sockopt flags */
|
||||||
__u8 recverr:1,
|
__u16 recverr:1,
|
||||||
sndflow:1,
|
sndflow:1,
|
||||||
pmtudisc:2,
|
pmtudisc:2,
|
||||||
ipv6only:1,
|
ipv6only:1,
|
||||||
srcprefs:3; /* 001: prefer temporary address
|
srcprefs:3, /* 001: prefer temporary address
|
||||||
* 010: prefer public address
|
* 010: prefer public address
|
||||||
* 100: prefer care-of address
|
* 100: prefer care-of address
|
||||||
*/
|
*/
|
||||||
|
dontfrag:1;
|
||||||
__u8 min_hopcount;
|
__u8 min_hopcount;
|
||||||
__u8 tclass;
|
__u8 tclass;
|
||||||
|
__u8 padding;
|
||||||
|
|
||||||
__u32 dst_cookie;
|
__u32 dst_cookie;
|
||||||
|
|
||||||
|
@@ -337,6 +337,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
|||||||
retv = 0;
|
retv = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IPV6_RECVPATHMTU:
|
||||||
|
if (optlen < sizeof(int))
|
||||||
|
goto e_inval;
|
||||||
|
np->rxopt.bits.rxpmtu = valbool;
|
||||||
|
retv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case IPV6_HOPOPTS:
|
case IPV6_HOPOPTS:
|
||||||
case IPV6_RTHDRDSTOPTS:
|
case IPV6_RTHDRDSTOPTS:
|
||||||
case IPV6_RTHDR:
|
case IPV6_RTHDR:
|
||||||
@@ -773,6 +780,9 @@ pref_skip_coa:
|
|||||||
if (val < 0 || val > 255)
|
if (val < 0 || val > 255)
|
||||||
goto e_inval;
|
goto e_inval;
|
||||||
np->min_hopcount = val;
|
np->min_hopcount = val;
|
||||||
|
break;
|
||||||
|
case IPV6_DONTFRAG:
|
||||||
|
np->dontfrag = valbool;
|
||||||
retv = 0;
|
retv = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1063,6 +1073,38 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
|
|||||||
val = np->rxopt.bits.rxflow;
|
val = np->rxopt.bits.rxflow;
|
||||||
break;
|
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_UNICAST_HOPS:
|
||||||
case IPV6_MULTICAST_HOPS:
|
case IPV6_MULTICAST_HOPS:
|
||||||
{
|
{
|
||||||
@@ -1128,6 +1170,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
|
|||||||
val = np->min_hopcount;
|
val = np->min_hopcount;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IPV6_DONTFRAG:
|
||||||
|
val = np->dontfrag;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user