diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2008-04-24 21:30:38 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-24 21:30:38 -0700 |
commit | 1a98d05f59704d60be85b03f727964e15c77224c (patch) | |
tree | ae125c4ff89a650368dbedcc5337ce2cfa5f1d98 /net | |
parent | 8d390efd903485923419584275fd0c2aa4c94183 (diff) | |
download | kernel_samsung_smdk4412-1a98d05f59704d60be85b03f727964e15c77224c.zip kernel_samsung_smdk4412-1a98d05f59704d60be85b03f727964e15c77224c.tar.gz kernel_samsung_smdk4412-1a98d05f59704d60be85b03f727964e15c77224c.tar.bz2 |
ipv6 RAW: Disallow IPPROTO_IPV6-level IPV6_CHECKSUM socket option on ICMPv6 sockets.
RFC3542 tells that IPV6_CHECKSUM socket option in the IPPROTO_IPV6
level is not allowed on ICMPv6 sockets. IPPROTO_RAW level
IPV6_CHECKSUM socket option (a Linux extension) is still allowed.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/raw.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 6193b12..396f0ea 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -971,6 +971,19 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, switch (optname) { case IPV6_CHECKSUM: + if (inet_sk(sk)->num == IPPROTO_ICMPV6 && + level == IPPROTO_IPV6) { + /* + * RFC3542 tells that IPV6_CHECKSUM socket + * option in the IPPROTO_IPV6 level is not + * allowed on ICMPv6 sockets. + * If you want to set it, use IPPROTO_RAW + * level IPV6_CHECKSUM socket option + * (Linux extension). + */ + return -EINVAL; + } + /* You may get strange result with a positive odd offset; RFC2292bis agrees with me. */ if (val > 0 && (val&1)) @@ -1046,6 +1059,11 @@ static int do_rawv6_getsockopt(struct sock *sk, int level, int optname, switch (optname) { case IPV6_CHECKSUM: + /* + * We allow getsockopt() for IPPROTO_IPV6-level + * IPV6_CHECKSUM socket option on ICMPv6 sockets + * since RFC3542 is silent about it. + */ if (rp->checksum == 0) val = -1; else |