Consolidate cases for IPV6_2292HOPOPTS, IPV6_HOPOPTS, IPV6_2292DSTOPTS,
IPV6_DSTOPTS, and IPV6_RTHDRDSTOPTS. Most of the work and verifications
are common for all these case, individual differences in processing can
be implemented with an embedded switch statement.
---
 net/ipv6/datagram.c | 66 ++++++++++++++++++-----------------------------------
 1 file changed, 22 insertions(+), 44 deletions(-)

diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index ee4a4e5..f4742db 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -842,49 +842,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
 
                case IPV6_2292HOPOPTS:
                case IPV6_HOPOPTS:
-                       if (opt->hopopt || cmsg->cmsg_len < 
CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-
-                       hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
-                       len = ((hdr->hdrlen + 1) << 3);
-                       if (cmsg->cmsg_len < CMSG_LEN(len)) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-                       if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
-                               err = -EPERM;
-                               goto exit_f;
-                       }
-                       opt->opt_nflen += len;
-                       opt->hopopt = hdr;
-                       break;
-
                case IPV6_2292DSTOPTS:
-                       if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct 
ipv6_opt_hdr))) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-
-                       hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
-                       len = ((hdr->hdrlen + 1) << 3);
-                       if (cmsg->cmsg_len < CMSG_LEN(len)) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-                       if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
-                               err = -EPERM;
-                               goto exit_f;
-                       }
-                       if (opt->dst1opt) {
-                               err = -EINVAL;
-                               goto exit_f;
-                       }
-                       opt->opt_flen += len;
-                       opt->dst1opt = hdr;
-                       break;
-
                case IPV6_DSTOPTS:
                case IPV6_RTHDRDSTOPTS:
                        if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct 
ipv6_opt_hdr))) {
@@ -902,13 +860,33 @@ int ip6_datagram_send_ctl(struct net *net, struct sock 
*sk,
                                err = -EPERM;
                                goto exit_f;
                        }
-                       if (cmsg->cmsg_type == IPV6_DSTOPTS) {
+
+                       switch (cmsg->cmsg_type) {
+                       case IPV6_2292HOPOPTS:
+                       case IPV6_HOPOPTS:
+                               if (opt->hopopt) {
+                                       err = -EINVAL;
+                                       goto exit_f;
+                               }
+                               opt->opt_nflen += len;
+                               opt->hopopt = hdr;
+                               break;
+                       case IPV6_2292DSTOPTS:
+                               if (opt->dst1opt) {
+                                       err = -EINVAL;
+                                       goto exit_f;
+                               }
+                               /* Fallthrough */
+                       case IPV6_DSTOPTS:
                                opt->opt_flen += len;
                                opt->dst1opt = hdr;
-                       } else {
+                               break;
+                       case IPV6_RTHDRDSTOPTS:
                                opt->opt_nflen += len;
                                opt->dst0opt = hdr;
+                               break;
                        }
+
                        break;
 
                case IPV6_2292RTHDR:
-- 
2.7.4

Reply via email to