This patch fixes two bugs:
1. setsockopt() of anything but a Type 2 routing header should return
EINVAL instead of EPERM.  Noticed by Shan Wei
(shanwei@cn.fujitsu.com).
2. setsockopt()/sendmsg() of a Type 2 routing header with invalid
length or segments should return EINVAL.  These values are statically
fixed in RFC 3775, unlike the variable Type 0 was.
Signed-off-by: Brian Haley <brian.haley@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
                        switch (rthdr->type) {
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        case IPV6_SRCRT_TYPE_2:
+                               if (rthdr->hdrlen != 2 ||
+                                   rthdr->segments_left != 1) {
+                                       err = -EINVAL;
+                                       goto exit_f;
+                               }
                                break;
 #endif
                        default:
 
                }
 
                /* routing header option needs extra check */
+               retv = -EINVAL;
                if (optname == IPV6_RTHDR && opt && opt->srcrt) {
                        struct ipv6_rt_hdr *rthdr = opt->srcrt;
                        switch (rthdr->type) {
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                        case IPV6_SRCRT_TYPE_2:
+                               if (rthdr->hdrlen != 2 ||
+                                   rthdr->segments_left != 1)
+                                       goto sticky_done;
+
                                break;
 #endif
                        default: