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