tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

ip6_[gs]etmoptions sockopt conversion



Hi,
   Below is a patch to convert ip6_[gs]etmoptions to use sockopt instead
of the legacy mbuf code. Its a fairly simple change with no functional
differences, but since we are still in feature freeze if anybody could
review that would be great.

thanks,
iain

--- /usr/src/sys/netinet6/ip6_output.c  2008-08-06 16:17:06.000000000 +0100
+++ ip6_output.c        2008-08-18 11:27:06.000000000 +0100
@@ -132,8 +132,8 @@ static int ip6_pcbopt(int, u_char *, int
 static int ip6_getpcbopt(struct ip6_pktopts *, int, struct sockopt *);
 static int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, int,
        int, int, int);
-static int ip6_setmoptions(int, struct ip6_moptions **, struct mbuf *);
-static int ip6_getmoptions(int, struct ip6_moptions *, struct mbuf **);
+static int ip6_setmoptions(const struct sockopt *, struct ip6_moptions **);
+static int ip6_getmoptions(struct sockopt *, struct ip6_moptions *);
 static int ip6_copyexthdr(struct mbuf **, void *, int);
 static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int,
        struct ip6_frag **);
@@ -1797,18 +1797,9 @@ else                                     \
                case IPV6_MULTICAST_HOPS:
                case IPV6_MULTICAST_LOOP:
                case IPV6_JOIN_GROUP:
-               case IPV6_LEAVE_GROUP: {
-                       struct mbuf *m;
-
-                       m = sockopt_getmbuf(sopt);
-                       if (m == NULL) {
-                               error = ENOMEM;
-                               break;
-                       }
-                       error = ip6_setmoptions(optname,
-                           &in6p->in6p_moptions, m);
+               case IPV6_LEAVE_GROUP:
+                       error = ip6_setmoptions(sopt, &in6p->in6p_moptions);
                        break;
-                       }

                case IPV6_PORTRANGE:
                        error = sockopt_getint(sopt, &optval);
@@ -2018,15 +2009,9 @@ else                                     \
                case IPV6_MULTICAST_HOPS:
                case IPV6_MULTICAST_LOOP:
                case IPV6_JOIN_GROUP:
-               case IPV6_LEAVE_GROUP: {
-                       struct mbuf *m;
-
-                       error = ip6_getmoptions(optname,
-                           in6p->in6p_moptions, &m);
-                       if (!error)
-                               error = sockopt_setmbuf(sopt, m);
+               case IPV6_LEAVE_GROUP:
+                       error = ip6_getmoptions(sopt, in6p->in6p_moptions);
                        break;
-                       }

 #if defined(IPSEC) || defined(FAST_IPSEC)
                case IPV6_IPSEC_POLICY:
@@ -2422,11 +2407,11 @@ ip6_freepcbopts(struct ip6_pktopts *pkto
  * Set the IP6 multicast options in response to user setsockopt().
  */
 static int
-ip6_setmoptions(int optname, struct ip6_moptions **im6op, struct mbuf *m)
+ip6_setmoptions(const struct sockopt *sopt, struct ip6_moptions **im6op)
 {
        int error = 0;
        u_int loop, ifindex;
-       struct ipv6_mreq *mreq;
+       struct ipv6_mreq mreq;
        struct ifnet *ifp;
        struct ip6_moptions *im6o = *im6op;
        struct route ro;
@@ -2450,17 +2435,16 @@ ip6_setmoptions(int optname, struct ip6_
                LIST_INIT(&im6o->im6o_memberships);
        }

-       switch (optname) {
+       switch (sopt->sopt_name) {

        case IPV6_MULTICAST_IF:
                /*
                 * Select the interface for outgoing multicast packets.
                 */
-               if (m == NULL || m->m_len != sizeof(u_int)) {
-                       error = EINVAL;
+               error = sockopt_get(sopt, &ifindex, sizeof(ifindex));
+               if (error != 0)
                        break;
-               }
-               bcopy(mtod(m, u_int *), &ifindex, sizeof(ifindex));
+
                if (ifindex != 0) {
                        if (if_indexlim <= ifindex || !ifindex2ifnet[ifindex]) {
                                error = ENXIO;  /* XXX EINVAL? */
@@ -2482,11 +2466,11 @@ ip6_setmoptions(int optname, struct ip6_
                 * Set the IP6 hoplimit for outgoing multicast packets.
                 */
                int optval;
-               if (m == NULL || m->m_len != sizeof(int)) {
-                       error = EINVAL;
+
+               error = sockopt_getint(sopt, &optval);
+               if (error != 0)
                        break;
-               }
-               bcopy(mtod(m, u_int *), &optval, sizeof(optval));
+
                if (optval < -1 || optval >= 256)
                        error = EINVAL;
                else if (optval == -1)
@@ -2501,11 +2485,9 @@ ip6_setmoptions(int optname, struct ip6_
                 * Set the loopback flag for outgoing multicast packets.
                 * Must be zero or one.
                 */
-               if (m == NULL || m->m_len != sizeof(u_int)) {
-                       error = EINVAL;
+               error = sockopt_get(sopt, &loop, sizeof(loop));
+               if (error != 0)
                        break;
-               }
-               bcopy(mtod(m, u_int *), &loop, sizeof(loop));
                if (loop > 1) {
                        error = EINVAL;
                        break;
@@ -2518,12 +2500,11 @@ ip6_setmoptions(int optname, struct ip6_
                 * Add a multicast group membership.
                 * Group must be a valid IP6 multicast address.
                 */
-               if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
-                       error = EINVAL;
+               error = sockopt_get(sopt, &mreq, sizeof(mreq));
+               if (error != 0)
                        break;
-               }
-               mreq = mtod(m, struct ipv6_mreq *);
-               if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
+
+               if (IN6_IS_ADDR_UNSPECIFIED(&mreq.ipv6mr_multiaddr)) {
                        /*
                         * We use the unspecified address to specify to accept
                         * all multicast addresses. Only super user is allowed
@@ -2535,7 +2516,7 @@ ip6_setmoptions(int optname, struct ip6_
                                error = EACCES;
                                break;
                        }
-               } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
+               } else if (!IN6_IS_ADDR_MULTICAST(&mreq.ipv6mr_multiaddr)) {
                        error = EINVAL;
                        break;
                }
@@ -2544,7 +2525,7 @@ ip6_setmoptions(int optname, struct ip6_
                 * If no interface was explicitly specified, choose an
                 * appropriate one according to the given multicast address.
                 */
-               if (mreq->ipv6mr_interface == 0) {
+               if (mreq.ipv6mr_interface == 0) {
                        struct rtentry *rt;
                        union {
                                struct sockaddr         dst;
@@ -2557,7 +2538,7 @@ ip6_setmoptions(int optname, struct ip6_
                         *   XXX: is it a good approach?
                         */
                        memset(&ro, 0, sizeof(ro));
-                       sockaddr_in6_init(&u.dst6, &mreq->ipv6mr_multiaddr, 0,
+                       sockaddr_in6_init(&u.dst6, &mreq.ipv6mr_multiaddr, 0,
                            0, 0);
                        rtcache_setdst(&ro, &u.dst);
                        ifp = (rt = rtcache_init(&ro)) != NULL ? rt->rt_ifp
@@ -2567,12 +2548,12 @@ ip6_setmoptions(int optname, struct ip6_
                        /*
                         * If the interface is specified, validate it.
                         */
-                       if (if_indexlim <= mreq->ipv6mr_interface ||
-                           !ifindex2ifnet[mreq->ipv6mr_interface]) {
+                       if (if_indexlim <= mreq.ipv6mr_interface ||
+                           !ifindex2ifnet[mreq.ipv6mr_interface]) {
                                error = ENXIO;  /* XXX EINVAL? */
                                break;
                        }
-                       ifp = ifindex2ifnet[mreq->ipv6mr_interface];
+                       ifp = ifindex2ifnet[mreq.ipv6mr_interface];
                }

                /*
@@ -2584,7 +2565,7 @@ ip6_setmoptions(int optname, struct ip6_
                        break;
                }

-               if (in6_setscope(&mreq->ipv6mr_multiaddr, ifp, NULL)) {
+               if (in6_setscope(&mreq.ipv6mr_multiaddr, ifp, NULL)) {
                        error = EADDRNOTAVAIL; /* XXX: should not happen */
                        break;
                }
@@ -2596,7 +2577,7 @@ ip6_setmoptions(int optname, struct ip6_
                     imm != NULL; imm = imm->i6mm_chain.le_next)
                        if (imm->i6mm_maddr->in6m_ifp == ifp &&
                            IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
-                           &mreq->ipv6mr_multiaddr))
+                           &mreq.ipv6mr_multiaddr))
                                break;
                if (imm != NULL) {
                        error = EADDRINUSE;
@@ -2606,7 +2587,7 @@ ip6_setmoptions(int optname, struct ip6_
                 * Everything looks good; add a new record to the multicast
                 * address list for the given interface.
                 */
-               imm = in6_joingroup(ifp, &mreq->ipv6mr_multiaddr, &error, 0);
+               imm = in6_joingroup(ifp, &mreq.ipv6mr_multiaddr, &error, 0);
                if (imm == NULL)
                        break;
                LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
@@ -2617,34 +2598,32 @@ ip6_setmoptions(int optname, struct ip6_
                 * Drop a multicast group membership.
                 * Group must be a valid IP6 multicast address.
                 */
-               if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
-                       error = EINVAL;
+               error = sockopt_get(sopt, &mreq, sizeof(mreq));
+               if (error != 0)
                        break;
-               }
-               mreq = mtod(m, struct ipv6_mreq *);

                /*
                 * If an interface address was specified, get a pointer
                 * to its ifnet structure.
                 */
-               if (mreq->ipv6mr_interface != 0) {
-                       if (if_indexlim <= mreq->ipv6mr_interface ||
-                           !ifindex2ifnet[mreq->ipv6mr_interface]) {
+               if (mreq.ipv6mr_interface != 0) {
+                       if (if_indexlim <= mreq.ipv6mr_interface ||
+                           !ifindex2ifnet[mreq.ipv6mr_interface]) {
                                error = ENXIO;  /* XXX EINVAL? */
                                break;
                        }
-                       ifp = ifindex2ifnet[mreq->ipv6mr_interface];
+                       ifp = ifindex2ifnet[mreq.ipv6mr_interface];
                } else
                        ifp = NULL;

                /* Fill in the scope zone ID */
                if (ifp) {
-                       if (in6_setscope(&mreq->ipv6mr_multiaddr, ifp, NULL)) {
+                       if (in6_setscope(&mreq.ipv6mr_multiaddr, ifp, NULL)) {
                                /* XXX: should not happen */
                                error = EADDRNOTAVAIL;
                                break;
                        }
-               } else if (mreq->ipv6mr_interface != 0) {
+               } else if (mreq.ipv6mr_interface != 0) {
                        /*
                         * XXX: This case would happens when the (positive)
                         * index is in the valid range, but the corresponding
@@ -2667,12 +2646,12 @@ ip6_setmoptions(int optname, struct ip6_
                         * check if there's ambiguity with the default scope
                         * zone as the last resort.
                         */
-                       sockaddr_in6_init(&sa6_mc, &mreq->ipv6mr_multiaddr,
+                       sockaddr_in6_init(&sa6_mc, &mreq.ipv6mr_multiaddr,
                            0, 0, 0);
                        error = sa6_embedscope(&sa6_mc, ip6_use_defzone);
                        if (error != 0)
                                break;
-                       mreq->ipv6mr_multiaddr = sa6_mc.sin6_addr;
+                       mreq.ipv6mr_multiaddr = sa6_mc.sin6_addr;
                }

                /*
@@ -2682,7 +2661,7 @@ ip6_setmoptions(int optname, struct ip6_
                     imm != NULL; imm = imm->i6mm_chain.le_next) {
                        if ((ifp == NULL || imm->i6mm_maddr->in6m_ifp == ifp) &&
                            IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
-                           &mreq->ipv6mr_multiaddr))
+                           &mreq.ipv6mr_multiaddr))
                                break;
                }
                if (imm == NULL) {
@@ -2721,44 +2700,44 @@ ip6_setmoptions(int optname, struct ip6_
  * Return the IP6 multicast options in response to user getsockopt().
  */
 static int
-ip6_getmoptions(int optname, struct ip6_moptions *im6o, struct mbuf **mp)
+ip6_getmoptions(struct sockopt *sopt, struct ip6_moptions *im6o)
 {
-       u_int *hlim, *loop, *ifindex;
-
-       *mp = m_get(M_WAIT, MT_SOOPTS);
-
-       switch (optname) {
+       u_int optval;
+       int error;

+       switch (sopt->sopt_name) {
        case IPV6_MULTICAST_IF:
-               ifindex = mtod(*mp, u_int *);
-               (*mp)->m_len = sizeof(u_int);
                if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
-                       *ifindex = 0;
+                       optval = 0;
                else
-                       *ifindex = im6o->im6o_multicast_ifp->if_index;
-               return (0);
+                       optval = im6o->im6o_multicast_ifp->if_index;
+
+               error = sockopt_set(sopt, &optval, sizeof(optval));
+               break;

        case IPV6_MULTICAST_HOPS:
-               hlim = mtod(*mp, u_int *);
-               (*mp)->m_len = sizeof(u_int);
                if (im6o == NULL)
-                       *hlim = ip6_defmcasthlim;
+                       optval = ip6_defmcasthlim;
                else
-                       *hlim = im6o->im6o_multicast_hlim;
-               return (0);
+                       optval = im6o->im6o_multicast_hlim;
+
+               error = sockopt_set(sopt, &optval, sizeof(optval));
+               break;

        case IPV6_MULTICAST_LOOP:
-               loop = mtod(*mp, u_int *);
-               (*mp)->m_len = sizeof(u_int);
                if (im6o == NULL)
-                       *loop = ip6_defmcasthlim;
+                       optval = ip6_defmcasthlim;
                else
-                       *loop = im6o->im6o_multicast_loop;
-               return (0);
+                       optval = im6o->im6o_multicast_loop;
+
+               error = sockopt_set(sopt, &optval, sizeof(optval));
+               break;

        default:
-               return (EOPNOTSUPP);
+               error = EOPNOTSUPP;
        }
+
+       return (error);
 }

 /*


Home | Main Index | Thread Index | Old Index