Remove IPX over IP tunneling support, which allows IPX routing over IP

tunnels, and was not MPSAFE.  The code can be easily restored in the
event that someone with an IPX over IP tunnel configuration can work
with me to test patches.

This removes one of five remaining consumers of NET_NEEDS_GIANT.

Approved by:	re (kensmith)
This commit is contained in:
Robert Watson 2007-06-13 14:01:43 +00:00
parent 77764a595a
commit 2281b8f054
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170664
10 changed files with 2 additions and 588 deletions

View File

@ -516,7 +516,6 @@ options IPSEC_DEBUG #debug for IP security
#options FAST_IPSEC #new IPsec (cannot define w/ IPSEC)
options IPX #IPX/SPX communications protocols
options IPXIP #IPX in IP encapsulation (not available)
options NCP #NetWare Core protocol

View File

@ -1908,7 +1908,6 @@ netipsec/xform_tcp.c optional fast_ipsec tcp_signature
netipx/ipx.c optional ipx
netipx/ipx_cksum.c optional ipx
netipx/ipx_input.c optional ipx
netipx/ipx_ip.c optional ipx ipxip
netipx/ipx_outputfl.c optional ipx
netipx/ipx_pcb.c optional ipx
netipx/ipx_proto.c optional ipx

View File

@ -376,7 +376,6 @@ IPFIREWALL_FORWARD opt_ipfw.h
IPFIREWALL_NAT opt_ipfw.h
IPSTEALTH
IPX
IPXIP opt_ipx.h
LIBMBPOOL
LIBMCHAIN
LIBALIAS

View File

@ -250,5 +250,5 @@
#define IFT_PFLOG 0xf6
#define IFT_PFSYNC 0xf7
#define IFT_CARP 0xf8 /* Common Address Redundancy Protocol */
#define IFT_IPXIP 0xf9
#define IFT_IPXIP 0xf9 /* IPX over IP tunneling; no longer used. */
#endif /* !_NET_IF_TYPES_H_ */

View File

@ -82,10 +82,6 @@ static struct pr_usrreqs nousrreqs;
#include <netipsec/ipsec.h>
#endif /* FAST_IPSEC */
#ifdef IPXIP
#include <netipx/ipx_ip.h>
#endif
#ifdef SCTP
#include <netinet/in_pcb.h>
#include <netinet/sctp_pcb.h>
@ -331,17 +327,6 @@ struct protosw inetsw[] = {
.pr_usrreqs = &rip_usrreqs
},
#endif
#ifdef IPXIP
{
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_IDP,
.pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR,
.pr_input = ipxip_input,
.pr_ctlinput = ipxip_ctlinput,
.pr_usrreqs = &rip_usrreqs
},
#endif
{
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,

View File

@ -115,7 +115,7 @@
#define SO_HEADERS_ON_OUTPUT 2
#define SO_DEFAULT_HEADERS 3
#define SO_LAST_HEADER 4
#define SO_IPXIP_ROUTE 5
#define SO_IPXIP_ROUTE 5 /* No longer implemented. */
#define SO_SEQNO 6
#define SO_ALL_PACKETS 7
#define SO_MTU 8

View File

@ -104,14 +104,6 @@ struct ipx_aliasreq {
#define ETHERTYPE_IPX 0x8137 /* Only Ethernet_II Available */
#ifdef IPXIP
struct ipxip_req {
struct sockaddr rq_ipx; /* must be ipx format destination */
struct sockaddr rq_ip; /* must be ip format gateway */
short rq_flags;
};
#endif
#ifdef _KERNEL
extern struct ipx_ifaddr *ipx_ifaddr;

View File

@ -1,471 +0,0 @@
/*-
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1995, Mike Mitchell
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ipx_ip.c
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Software interface driver for encapsulating IPX in IP.
*/
#include "opt_inet.h"
#include "opt_ipx.h"
#ifndef INET
#error The option IPXIP requires option INET.
#endif
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_options.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#include <netipx/ipx_ip.h>
#include <netipx/ipx_var.h>
NET_NEEDS_GIANT("ipx_ip");
static struct ifnet ipxipif;
static int ipxipif_units;
/* List of all hosts and gateways or broadcast addrs. */
static struct ifnet_en *ipxip_list;
static struct ifreq ifr_ipxip = {"ipxip0"};
static struct mbuf *ipxip_badlen;
static struct mbuf *ipxip_lastin;
static int ipxip_hold_input;
static struct ifnet_en *ipxipattach(void);
static int ipxip_free(struct ifnet *ifp);
static int ipxipioctl(struct ifnet *ifp, u_long cmd,
caddr_t data);
static int ipxipoutput(struct ifnet *ifp, struct mbuf *m,
struct sockaddr *dst, struct rtentry *rt);
static void ipxip_rtchange(struct in_addr *dst);
static void ipxipstart(struct ifnet *ifp);
static struct ifnet_en *
ipxipattach(void)
{
struct ifnet_en *m;
struct ifnet *ifp;
if (ipxipif.if_mtu == 0) {
ifp = &ipxipif;
if_initname(ifp, "ipxip", ipxipif_units);
ifp->if_mtu = LOMTU;
ifp->if_ioctl = ipxipioctl;
ifp->if_output = ipxipoutput;
ifp->if_start = ipxipstart;
ifp->if_flags = IFF_POINTOPOINT;
}
MALLOC((m), struct ifnet_en *, sizeof(*m), M_PCB, M_NOWAIT | M_ZERO);
if (m == NULL)
return (NULL);
m->ifen_next = ipxip_list;
ipxip_list = m;
ifp = m->ifen_ifp = if_alloc(IFT_IPXIP);
if (ifp == NULL) {
FREE(m, M_PCB);
return (NULL);
}
if_initname(ifp, "ipxip", ipxipif_units++);
ifp->if_mtu = LOMTU;
ifp->if_ioctl = ipxipioctl;
ifp->if_output = ipxipoutput;
ifp->if_start = ipxipstart;
ifp->if_flags = IFF_POINTOPOINT;
ifp->if_softc = m;
if_attach(ifp);
return (m);
}
/*
* Process an ioctl request.
*/
static int
ipxipioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
int error = 0;
struct ifreq *ifr;
switch (cmd) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
/* FALLTHROUGH */
case SIOCSIFDSTADDR:
/*
* Everything else is done at a higher level.
*/
break;
case SIOCSIFFLAGS:
ifr = (struct ifreq *)data;
if ((ifr->ifr_flags & IFF_UP) == 0)
error = ipxip_free(ifp);
break;
default:
error = EINVAL;
}
return (error);
}
void
ipxip_input(struct mbuf *m, int hlen)
{
struct ip *ip;
struct ipx *ipx;
int len, s;
if (ipxip_hold_input) {
if (ipxip_lastin != NULL)
m_freem(ipxip_lastin);
ipxip_lastin = m_copym(m, 0, (int)M_COPYALL, M_DONTWAIT);
}
/*
* Get IP and IPX header together in first mbuf.
*/
ipxipif.if_ipackets++;
s = sizeof(struct ip) + sizeof(struct ipx);
if (((m->m_flags & M_EXT) || m->m_len < s) &&
(m = m_pullup(m, s)) == NULL) {
ipxipif.if_ierrors++;
return;
}
ip = mtod(m, struct ip *);
if (ip->ip_hl > (sizeof(struct ip) >> 2)) {
ip_stripoptions(m, (struct mbuf *)NULL);
if (m->m_len < s) {
if ((m = m_pullup(m, s)) == NULL) {
ipxipif.if_ierrors++;
return;
}
ip = mtod(m, struct ip *);
}
}
/*
* Make mbuf data length reflect IPX length. If not enough data to
* reflect IPX length, drop.
*/
m->m_data += sizeof(struct ip);
m->m_len -= sizeof(struct ip);
m->m_pkthdr.len -= sizeof(struct ip);
ipx = mtod(m, struct ipx *);
len = ntohs(ipx->ipx_len);
if (len & 1)
len++; /* Preserve Garbage Byte */
if (ip->ip_len != len) {
if (len > ip->ip_len) {
ipxipif.if_ierrors++;
if (ipxip_badlen)
m_freem(ipxip_badlen);
ipxip_badlen = m;
return;
}
/*
* Any extra will be trimmed off by the IPX routines.
*/
}
/*
* Deliver to IPX.
*/
netisr_dispatch(NETISR_IPX, m);
}
static int
ipxipoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
struct rtentry *rt)
{
struct ifnet_en *ifn = (struct ifnet_en *)ifp->if_softc;
struct route *ro = &(ifn->ifen_route);
struct ipx *ipx = mtod(m, struct ipx *);
struct ip *ip;
int len = 0;
int error;
ifn->ifen_ifp->if_opackets++;
ipxipif.if_opackets++;
/*
* Calculate data length and make space for IP header.
*/
len = ntohs(ipx->ipx_len);
if (len & 1)
len++; /* Preserve Garbage Byte */
/*
* Following clause not necessary on VAX.
*/
if (3 & (intptr_t)m->m_data) {
/* force longword alignment of ip hdr */
struct mbuf *m0 = m_gethdr(MT_DATA, M_DONTWAIT);
if (m0 == NULL) {
m_freem(m);
return (ENOBUFS);
}
MH_ALIGN(m0, sizeof(struct ip));
m0->m_flags = m->m_flags & M_COPYFLAGS;
m0->m_next = m;
m0->m_len = sizeof(struct ip);
m0->m_pkthdr.len = m0->m_len + m->m_len;
m->m_flags &= ~M_PKTHDR;
m = m0;
} else {
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
if (m == NULL)
return (ENOBUFS);
}
/*
* Fill in IP header.
*/
ip = mtod(m, struct ip *);
*(long *)ip = 0;
ip->ip_p = IPPROTO_IDP;
ip->ip_src = ifn->ifen_src;
ip->ip_dst = ifn->ifen_dst;
ip->ip_len = (u_short)len + sizeof(struct ip);
ip->ip_ttl = MAXTTL;
/*
* Output final datagram.
*/
error = ip_output(m, (struct mbuf *)NULL, ro, SO_BROADCAST, NULL,
NULL);
if (error) {
ifn->ifen_ifp->if_oerrors++;
ifn->ifen_ifp->if_ierrors = error;
}
return (error);
}
static void
ipxipstart(struct ifnet *ifp)
{
panic("ipxip_start called\n");
}
int
ipxip_route(struct socket *so, struct sockopt *sopt)
{
struct in_ifaddr *ia;
struct ifnet_en *ifn;
struct sockaddr_in *src;
struct ipxip_req rq;
struct sockaddr_ipx *ipx_dst;
struct sockaddr_in *ip_dst;
struct ifnet *ifp;
struct route ro;
int error;
error = sooptcopyin(sopt, &rq, sizeof rq, sizeof rq);
if (error)
return (error);
ipx_dst = (struct sockaddr_ipx *)&rq.rq_ipx;
ip_dst = (struct sockaddr_in *)&rq.rq_ip;
/*
* First, make sure we already have an IPX address:
*/
if (ipx_ifaddr == NULL)
return (EADDRNOTAVAIL);
/*
* Now, determine if we can get to the destination.
*/
bzero((caddr_t)&ro, sizeof(ro));
ro.ro_dst = *(struct sockaddr *)ip_dst;
rtalloc_ign(&ro, 0);
if (ro.ro_rt == NULL || ro.ro_rt->rt_ifp == NULL)
return (ENETUNREACH);
/*
* And see how he's going to get back to us: i.e., what return IP
* address do we use?
*/
ifp = ro.ro_rt->rt_ifp;
for (ia = TAILQ_FIRST(&in_ifaddrhead); ia != NULL;
ia = TAILQ_NEXT(ia, ia_link))
if (ia->ia_ifp == ifp)
break;
if (ia == NULL)
ia = TAILQ_FIRST(&in_ifaddrhead);
if (ia == NULL) {
RTFREE(ro.ro_rt);
return (EADDRNOTAVAIL);
}
src = (struct sockaddr_in *)&ia->ia_addr;
/*
* Is there a free (pseudo-)interface or space?
*/
for (ifn = ipxip_list; ifn != NULL; ifn = ifn->ifen_next) {
if ((ifn->ifen_ifp->if_flags & IFF_UP) == 0)
break;
}
if (ifn == NULL)
ifn = ipxipattach();
if (ifn == NULL) {
RTFREE(ro.ro_rt);
return (ENOBUFS);
}
ifn->ifen_route = ro;
ifn->ifen_dst = ip_dst->sin_addr;
ifn->ifen_src = src->sin_addr;
/*
* Now configure this as a point to point link.
*/
ifr_ipxip.ifr_name[4] = '0' + ipxipif_units - 1;
ifr_ipxip.ifr_dstaddr = *(struct sockaddr *)ipx_dst;
ipx_control(so, (int)SIOCSIFDSTADDR, (caddr_t)&ifr_ipxip,
(struct ifnet *)ifn, sopt->sopt_td);
/*
* Use any of our addresses.
*/
satoipx_addr(ifr_ipxip.ifr_addr).x_host =
ipx_ifaddr->ia_addr.sipx_addr.x_host;
return (ipx_control(so, (int)SIOCSIFADDR, (caddr_t)&ifr_ipxip,
(struct ifnet *)ifn, sopt->sopt_td));
}
static int
ipxip_free(struct ifnet *ifp)
{
struct ifnet_en *ifn = (struct ifnet_en *)ifp->if_softc;
struct route *ro = & ifn->ifen_route;
if (ro->ro_rt != NULL) {
RTFREE(ro->ro_rt);
ro->ro_rt = NULL;
}
ifp->if_flags &= ~IFF_UP;
return (0);
}
void
ipxip_ctlinput(int cmd, struct sockaddr *sa, void *dummy)
{
struct sockaddr_in *sin;
if ((unsigned)cmd >= PRC_NCMDS)
return;
if (sa->sa_family != AF_INET && sa->sa_family != AF_IMPLINK)
return;
sin = (struct sockaddr_in *)sa;
if (sin->sin_addr.s_addr == INADDR_ANY)
return;
switch (cmd) {
case PRC_ROUTEDEAD:
case PRC_REDIRECT_NET:
case PRC_REDIRECT_HOST:
case PRC_REDIRECT_TOSNET:
case PRC_REDIRECT_TOSHOST:
ipxip_rtchange(&sin->sin_addr);
break;
}
}
static void
ipxip_rtchange(struct in_addr *dst)
{
struct ifnet_en *ifn;
for (ifn = ipxip_list; ifn != NULL; ifn = ifn->ifen_next) {
if (ifn->ifen_dst.s_addr == dst->s_addr &&
ifn->ifen_route.ro_rt != NULL) {
RTFREE(ifn->ifen_route.ro_rt);
ifn->ifen_route.ro_rt = NULL;
}
}
}

View File

@ -1,83 +0,0 @@
/*-
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 1995, Mike Mitchell
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ipxip.h
*
* $FreeBSD$
*/
#ifndef _NETIPX_IPXIP_H_
#define _NETIPX_IPXIP_H_
struct ifnet_en {
struct ifnet *ifen_ifp;
struct route ifen_route;
struct in_addr ifen_src;
struct in_addr ifen_dst;
struct ifnet_en *ifen_next;
};
#define LOMTU (1024+512) /* XXX this is TINY_LOMTU */
#ifdef _KERNEL
void ipxip_ctlinput(int cmd, struct sockaddr *sa, void *arg);
void ipxip_input(struct mbuf *m, int hlen);
int ipxip_route(struct socket *so, struct sockopt *sopt);
#endif
#endif /* !_NETIPX_IPXIP_H_ */

View File

@ -87,7 +87,6 @@ __FBSDID("$FreeBSD$");
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#include <netipx/ipx_ip.h>
#include <netipx/ipx_pcb.h>
#include <netipx/ipx_var.h>
@ -437,11 +436,6 @@ ipx_ctloutput(struct socket *so, struct sockopt *sopt)
/* Unlocked write. */
ipxp->ipxp_dpt = ioptval.ipx_pt;
break;
#ifdef IPXIP
case SO_IPXIP_ROUTE:
error = ipxip_route(so, sopt);
break;
#endif /* IPXIP */
default:
error = EINVAL;
}