[Midnightbsd-cvs] src: sys/netipx: Sync with enhancements from FreeBSD 7.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Mon Sep 15 20:23:40 EDT 2008
Log Message:
-----------
Sync with enhancements from FreeBSD 7.
Modified Files:
--------------
src/sys/netipx:
README (r1.1.1.1 -> r1.2)
ipx.c (r1.1.1.1 -> r1.2)
ipx.h (r1.1.1.1 -> r1.2)
ipx_cksum.c (r1.1.1.1 -> r1.2)
ipx_if.h (r1.1.1.1 -> r1.2)
ipx_input.c (r1.1.1.2 -> r1.2)
ipx_outputfl.c (r1.1.1.1 -> r1.2)
ipx_pcb.c (r1.1.1.1 -> r1.2)
ipx_pcb.h (r1.1.1.1 -> r1.2)
ipx_proto.c (r1.1.1.1 -> r1.2)
ipx_usrreq.c (r1.1.1.1 -> r1.2)
ipx_var.h (r1.1.1.1 -> r1.2)
spx.h (r1.1.1.1 -> r1.2)
spx_debug.c (r1.1.1.1 -> r1.2)
spx_debug.h (r1.1.1.1 -> r1.2)
spx_timer.h (r1.1.1.1 -> r1.2)
spx_usrreq.c (r1.1.1.1 -> r1.2)
spx_var.h (r1.1.1.1 -> r1.2)
Removed Files:
-------------
src/sys/netipx:
ipx_ip.c
ipx_ip.h
-------------- next part --------------
Index: spx_debug.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/spx_debug.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/spx_debug.h -L sys/netipx/spx_debug.h -u -r1.1.1.1 -r1.2
--- sys/netipx/spx_debug.h
+++ sys/netipx/spx_debug.h
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -33,7 +58,7 @@
*
* @(#)spx_debug.h
*
- * $FreeBSD: src/sys/netipx/spx_debug.h,v 1.15 2005/01/07 01:45:47 imp Exp $
+ * $FreeBSD: src/sys/netipx/spx_debug.h,v 1.18 2007/07/30 11:06:42 des Exp $
*/
#ifndef _NETIPX_SPX_DEBUG_H_
@@ -70,10 +95,9 @@
#ifdef _KERNEL
extern char *prurequests[];
extern char *sanames[];
-extern char *tcpstates[];
-void spx_trace(int act, int ostate, struct spxpcb *sp, struct spx *si,
- int req);
+void spx_trace(short act, u_char ostate, struct spxpcb *sp, struct spx *si,
+ int req);
#endif
#endif /* !_NETIPX_SPX_DEBUG_H_ */
Index: ipx_outputfl.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_outputfl.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_outputfl.c -L sys/netipx/ipx_outputfl.c -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_outputfl.c
+++ sys/netipx/ipx_outputfl.c
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -35,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/ipx_outputfl.c,v 1.22 2005/01/07 01:45:47 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/ipx_outputfl.c,v 1.24 2007/05/11 10:38:34 rwatson Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -52,13 +77,10 @@
static int ipx_copy_output = 0;
int
-ipx_outputfl(m0, ro, flags)
- struct mbuf *m0;
- struct route *ro;
- int flags;
+ipx_outputfl(struct mbuf *m0, struct route *ro, int flags)
{
- register struct ipx *ipx = mtod(m0, struct ipx *);
- register struct ifnet *ifp = NULL;
+ struct ipx *ipx = mtod(m0, struct ipx *);
+ struct ifnet *ifp = NULL;
int error = 0;
struct sockaddr_ipx *dst;
struct route ipxroute;
@@ -157,10 +179,9 @@
* that have ipx configured and isn't in the list yet.
*/
int
-ipx_output_type20(m)
- struct mbuf *m;
+ipx_output_type20(struct mbuf *m)
{
- register struct ipx *ipx;
+ struct ipx *ipx;
union ipx_net *nbnet;
struct ipx_ifaddr *ia, *tia = NULL;
int error = 0;
Index: ipx_input.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_input.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netipx/ipx_input.c -L sys/netipx/ipx_input.c -u -r1.1.1.2 -r1.2
--- sys/netipx/ipx_input.c
+++ sys/netipx/ipx_input.c
@@ -1,8 +1,35 @@
/*-
+ * Copyright (c) 1984, 1985, 1986, 1987, 1993
+ * The Regents of the University of California.
* Copyright (c) 2004-2005 Robert N. M. Watson
+ * 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
- * Copyright (c) 1984, 1985, 1986, 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/ipx_input.c,v 1.51.2.1 2006/02/14 21:35:07 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/ipx_input.c,v 1.57 2007/05/11 10:38:34 rwatson Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -107,7 +134,7 @@
*/
void
-ipx_init()
+ipx_init(void)
{
read_random(&ipx_pexseq, sizeof ipx_pexseq);
@@ -135,8 +162,8 @@
static void
ipxintr(struct mbuf *m)
{
- register struct ipx *ipx;
- register struct ipxpcb *ipxp;
+ struct ipx *ipx;
+ struct ipxpcb *ipxp;
struct ipx_ifaddr *ia;
int len;
@@ -294,28 +321,8 @@
struct sockaddr *arg_as_sa; /* XXX should be swapped with dummy */
void *dummy;
{
- caddr_t arg = (/* XXX */ caddr_t)arg_as_sa;
- struct ipx_addr *ipx;
-
- if (cmd < 0 || cmd >= PRC_NCMDS)
- return;
- switch (cmd) {
- struct sockaddr_ipx *sipx;
-
- case PRC_IFDOWN:
- case PRC_HOSTDEAD:
- case PRC_HOSTUNREACH:
- sipx = (struct sockaddr_ipx *)arg;
- if (sipx->sipx_family != AF_IPX)
- return;
- ipx = &sipx->sipx_addr;
- break;
- default:
- if (ipxprintfs)
- printf("ipx_ctlinput: cmd %d.\n", cmd);
- break;
- }
+ /* Currently, nothing. */
}
/*
@@ -327,11 +334,10 @@
static struct route ipx_sroute;
static void
-ipx_forward(m)
-struct mbuf *m;
+ipx_forward(struct mbuf *m)
{
- register struct ipx *ipx = mtod(m, struct ipx *);
- register int error;
+ struct ipx *ipx = mtod(m, struct ipx *);
+ int error;
int agedelta = 1;
int flags = IPX_FORWARDING;
int ok_there = 0;
@@ -417,9 +423,7 @@
}
static int
-ipx_do_route(src, ro)
-struct ipx_addr *src;
-struct route *ro;
+ipx_do_route(struct ipx_addr *src, struct route *ro)
{
struct sockaddr_ipx *dst;
@@ -439,22 +443,25 @@
}
static void
-ipx_undo_route(ro)
-register struct route *ro;
+ipx_undo_route(struct route *ro)
{
+
if (ro->ro_rt != NULL) {
RTFREE(ro->ro_rt);
}
}
+/*
+ * XXXRW: This code should be run in its own netisr dispatch to avoid a call
+ * back into the socket code from the IPX output path.
+ */
void
-ipx_watch_output(m, ifp)
-struct mbuf *m;
-struct ifnet *ifp;
+ipx_watch_output(struct mbuf *m, struct ifnet *ifp)
{
- register struct ipxpcb *ipxp;
- register struct ifaddr *ifa;
- register struct ipx_ifaddr *ia;
+ struct ipxpcb *ipxp;
+ struct ifaddr *ifa;
+ struct ipx_ifaddr *ia;
+
/*
* Give any raw listeners a crack at the packet
*/
@@ -462,7 +469,7 @@
LIST_FOREACH(ipxp, &ipxrawpcb_list, ipxp_list) {
struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
if (m0 != NULL) {
- register struct ipx *ipx;
+ struct ipx *ipx;
M_PREPEND(m0, sizeof(*ipx), M_DONTWAIT);
if (m0 == NULL)
Index: spx_usrreq.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/spx_usrreq.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/spx_usrreq.c -L sys/netipx/spx_usrreq.c -u -r1.1.1.1 -r1.2
--- sys/netipx/spx_usrreq.c
+++ sys/netipx/spx_usrreq.c
@@ -1,8 +1,35 @@
/*-
- * Copyright (c) 2004-2005 Robert N. M. Watson
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California.
+ * Copyright (c) 2004-2006 Robert N. M. Watson
+ * 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
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/spx_usrreq.c,v 1.62 2005/02/21 21:58:17 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/spx_usrreq.c,v 1.86 2007/01/08 22:14:00 rwatson Exp $");
#include <sys/param.h>
#include <sys/lock.h>
@@ -65,13 +92,18 @@
/*
* SPX protocol implementation.
*/
+static struct mtx spx_mtx; /* Protects only spx_iss. */
static u_short spx_iss;
static u_short spx_newchecks[50];
static int spx_hardnosed;
static int spx_use_delack = 0;
static int traceallspxs = 0;
-static struct spx spx_savesi;
static struct spx_istat spx_istat;
+static int spxrexmtthresh = 3;
+
+#define SPX_LOCK_INIT() mtx_init(&spx_mtx, "spx_mtx", NULL, MTX_DEF)
+#define SPX_LOCK() mtx_lock(&spx_mtx)
+#define SPX_UNLOCK() mtx_unlock(&spx_mtx)
/* Following was struct spxstat spxstat; */
#ifndef spxstat
@@ -88,18 +120,20 @@
static int spx_reass(struct spxpcb *cb, struct spx *si);
static void spx_setpersist(struct spxpcb *cb);
static void spx_template(struct spxpcb *cb);
-static struct spxpcb *spx_timers(struct spxpcb *cb, int timer);
+static void spx_timers(struct spxpcb *cb, int timer);
static void spx_usrclosed(struct spxpcb *cb);
-static int spx_usr_abort(struct socket *so);
+static void spx_usr_abort(struct socket *so);
static int spx_accept(struct socket *so, struct sockaddr **nam);
static int spx_attach(struct socket *so, int proto, struct thread *td);
static int spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td);
+static void spx_usr_close(struct socket *so);
static int spx_connect(struct socket *so, struct sockaddr *nam,
struct thread *td);
-static int spx_detach(struct socket *so);
+static void spx_detach(struct socket *so);
+static void spx_pcbdetach(struct ipxpcb *ipxp);
static int spx_usr_disconnect(struct socket *so);
-static int spx_listen(struct socket *so, struct thread *td);
+static int spx_listen(struct socket *so, int backlog, struct thread *td);
static int spx_rcvd(struct socket *so, int flags);
static int spx_rcvoob(struct socket *so, struct mbuf *m, int flags);
static int spx_send(struct socket *so, int flags, struct mbuf *m,
@@ -124,6 +158,7 @@
.pru_send = spx_send,
.pru_shutdown = spx_shutdown,
.pru_sockaddr = ipx_sockaddr,
+ .pru_close = spx_usr_close,
};
struct pr_usrreqs spx_usrreq_sps = {
@@ -142,28 +177,29 @@
.pru_send = spx_send,
.pru_shutdown = spx_shutdown,
.pru_sockaddr = ipx_sockaddr,
+ .pru_close = spx_usr_close,
};
void
-spx_init()
+spx_init(void)
{
+ SPX_LOCK_INIT();
spx_iss = 1; /* WRONG !! should fish it out of TODR */
}
void
-spx_input(m, ipxp)
- register struct mbuf *m;
- register struct ipxpcb *ipxp;
-{
- register struct spxpcb *cb;
- register struct spx *si = mtod(m, struct spx *);
- register struct socket *so;
+spx_input(struct mbuf *m, struct ipxpcb *ipxp)
+{
+ struct spxpcb *cb;
+ struct spx *si = mtod(m, struct spx *);
+ struct socket *so;
+ struct spx spx_savesi;
int dropsocket = 0;
short ostate = 0;
spxstat.spxs_rcvtotal++;
- KASSERT(ipxp != NULL, ("spx_input: NULL ipxpcb"));
+ KASSERT(ipxp != NULL, ("spx_input: ipxpcb == NULL"));
/*
* spx_input() assumes that the caller will hold both the pcb list
@@ -175,8 +211,10 @@
IPX_LOCK_ASSERT(ipxp);
cb = ipxtospxpcb(ipxp);
- if (cb == NULL)
- goto bad;
+ KASSERT(cb != NULL, ("spx_input: cb == NULL"));
+
+ if (ipxp->ipxp_flags & IPXP_DROPPED)
+ goto drop;
if (m->m_len < sizeof(*si)) {
if ((m = m_pullup(m, sizeof(*si))) == NULL) {
@@ -192,6 +230,7 @@
si->si_alo = ntohs(si->si_alo);
so = ipxp->ipxp_socket;
+ KASSERT(so != NULL, ("spx_input: so == NULL"));
if (so->so_options & SO_DEBUG || traceallspxs) {
ostate = cb->s_state;
@@ -201,19 +240,26 @@
struct spxpcb *ocb = cb;
so = sonewconn(so, 0);
- if (so == NULL) {
+ if (so == NULL)
goto drop;
- }
+
/*
* This is ugly, but ....
*
- * Mark socket as temporary until we're
- * committed to keeping it. The code at
- * ``drop'' and ``dropwithreset'' check the
- * flag dropsocket to see if the temporary
- * socket created here should be discarded.
- * We mark the socket as discardable until
- * we're committed to it below in TCPS_LISTEN.
+ * Mark socket as temporary until we're committed to keeping
+ * it. The code at ``drop'' and ``dropwithreset'' check the
+ * flag dropsocket to see if the temporary socket created
+ * here should be discarded. We mark the socket as
+ * discardable until we're committed to it below in
+ * TCPS_LISTEN.
+ *
+ * XXXRW: In the new world order of real kernel parallelism,
+ * temporarily allocating the socket when we're "not sure"
+ * seems like a bad idea, as we might race to remove it if
+ * the listen socket is closed...?
+ *
+ * We drop the lock of the listen socket ipxp, and acquire
+ * the lock of the new socket ippx.
*/
dropsocket++;
IPX_UNLOCK(ipxp);
@@ -226,24 +272,24 @@
cb->s_flags2 = ocb->s_flags2; /* preserve sockopts */
cb->s_state = TCPS_LISTEN;
}
+ IPX_LOCK_ASSERT(ipxp);
/*
- * Packet received on connection.
- * reset idle time and keep-alive timer;
+ * Packet received on connection. Reset idle time and keep-alive
+ * timer.
*/
cb->s_idle = 0;
cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
switch (cb->s_state) {
-
case TCPS_LISTEN:{
struct sockaddr_ipx *sipx, ssipx;
struct ipx_addr laddr;
/*
- * If somebody here was carying on a conversation
- * and went away, and his pen pal thinks he can
- * still talk, we get the misdirected packet.
+ * If somebody here was carying on a conversation and went
+ * away, and his pen pal thinks he can still talk, we get the
+ * misdirected packet.
*/
if (spx_hardnosed && (si->si_did != 0 || si->si_seq != 0)) {
spx_istat.gonawy++;
@@ -275,13 +321,13 @@
cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
}
break;
- /*
- * This state means that we have heard a response
- * to our acceptance of their connection
- * It is probably logically unnecessary in this
- * implementation.
- */
+
case TCPS_SYN_RECEIVED: {
+ /*
+ * This state means that we have heard a response to our
+ * acceptance of their connection. It is probably logically
+ * unnecessary in this implementation.
+ */
if (si->si_did != cb->s_sid) {
spx_istat.wrncon++;
goto drop;
@@ -296,16 +342,15 @@
}
break;
- /*
- * This state means that we have gotten a response
- * to our attempt to establish a connection.
- * We fill in the data from the other side,
- * telling us which port to respond to, instead of the well-
- * known one we might have sent to in the first place.
- * We also require that this is a response to our
- * connection id.
- */
case TCPS_SYN_SENT:
+ /*
+ * This state means that we have gotten a response to our
+ * attempt to establish a connection. We fill in the data
+ * from the other side, telling us which port to respond to,
+ * instead of the well-known one we might have sent to in the
+ * first place. We also require that this is a response to
+ * our connection id.
+ */
if (si->si_did != cb->s_sid) {
spx_istat.notme++;
goto drop;
@@ -319,7 +364,9 @@
cb->s_flags |= SF_ACKNOW;
soisconnected(so);
cb->s_state = TCPS_ESTABLISHED;
- /* Use roundtrip time of connection request for initial rtt */
+ /*
+ * Use roundtrip time of connection request for initial rtt.
+ */
if (cb->s_rtt) {
cb->s_srtt = cb->s_rtt << 3;
cb->s_rttvar = cb->s_rtt << 1;
@@ -329,6 +376,7 @@
cb->s_rtt = 0;
}
}
+
if (so->so_options & SO_DEBUG || traceallspxs)
spx_trace(SA_INPUT, (u_char)ostate, cb, &spx_savesi, 0);
@@ -336,9 +384,8 @@
m->m_pkthdr.len -= sizeof(struct ipx);
m->m_data += sizeof(struct ipx);
- if (spx_reass(cb, si)) {
+ if (spx_reass(cb, si))
m_freem(m);
- }
if (cb->s_force || (cb->s_flags & (SF_ACKNOW|SF_WIN|SF_RXT)))
spx_output(cb, NULL);
cb->s_flags &= ~(SF_WIN|SF_RXT);
@@ -347,6 +394,10 @@
return;
dropwithreset:
+ IPX_LOCK_ASSERT(ipxp);
+ if (cb == NULL || (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG ||
+ traceallspxs))
+ spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0);
IPX_UNLOCK(ipxp);
if (dropsocket) {
struct socket *head;
@@ -360,43 +411,31 @@
so->so_head = NULL;
ACCEPT_UNLOCK();
soabort(so);
- cb = NULL;
}
IPX_LIST_UNLOCK();
- si->si_seq = ntohs(si->si_seq);
- si->si_ack = ntohs(si->si_ack);
- si->si_alo = ntohs(si->si_alo);
m_freem(dtom(si));
- if (cb == NULL || cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG ||
- traceallspxs)
- spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0);
return;
drop:
-bad:
- if (cb == NULL || cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG ||
- traceallspxs)
+ IPX_LOCK_ASSERT(ipxp);
+ if (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || traceallspxs)
spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0);
IPX_UNLOCK(ipxp);
IPX_LIST_UNLOCK();
m_freem(m);
}
-static int spxrexmtthresh = 3;
-
/*
- * This is structurally similar to the tcp reassembly routine
- * but its function is somewhat different: It merely queues
- * packets up, and suppresses duplicates.
+ * This is structurally similar to the tcp reassembly routine but its
+ * function is somewhat different: It merely queues packets up, and
+ * suppresses duplicates.
*/
static int
-spx_reass(cb, si)
-register struct spxpcb *cb;
-register struct spx *si;
-{
- register struct spx_q *q;
- register struct mbuf *m;
- register struct socket *so = cb->s_ipxpcb->ipxp_socket;
+spx_reass(struct spxpcb *cb, struct spx *si)
+{
+ struct spx_q *q;
+ struct mbuf *m;
+ struct socket *so = cb->s_ipxpcb->ipxp_socket;
char packetp = cb->s_flags & SF_HI;
int incr;
char wakeup = 0;
@@ -416,10 +455,10 @@
if ((si->si_cc & SPX_SP) && cb->s_rack != (cb->s_smax + 1)) {
spxstat.spxs_rcvdupack++;
/*
- * If this is a completely duplicate ack
- * and other conditions hold, we assume
- * a packet has been dropped and retransmit
- * it exactly as in tcp_input().
+ * If this is a completely duplicate ack and other
+ * conditions hold, we assume a packet has been
+ * dropped and retransmit it exactly as in
+ * tcp_input().
*/
if (si->si_ack != cb->s_rack ||
si->si_alo != cb->s_ralo)
@@ -445,25 +484,26 @@
goto update_window;
}
cb->s_dupacks = 0;
+
/*
- * If our correspondent acknowledges data we haven't sent
- * TCP would drop the packet after acking. We'll be a little
- * more permissive
+ * If our correspondent acknowledges data we haven't sent TCP would
+ * drop the packet after acking. We'll be a little more permissive.
*/
if (SSEQ_GT(si->si_ack, (cb->s_smax + 1))) {
spxstat.spxs_rcvacktoomuch++;
si->si_ack = cb->s_smax + 1;
}
spxstat.spxs_rcvackpack++;
+
/*
- * If transmit timer is running and timed sequence
- * number was acked, update smoothed round trip time.
- * See discussion of algorithm in tcp_input.c
+ * If transmit timer is running and timed sequence number was acked,
+ * update smoothed round trip time. See discussion of algorithm in
+ * tcp_input.c
*/
if (cb->s_rtt && SSEQ_GT(si->si_ack, cb->s_rtseq)) {
spxstat.spxs_rttupdated++;
if (cb->s_srtt != 0) {
- register short delta;
+ short delta;
delta = cb->s_rtt - (cb->s_srtt >> 3);
if ((cb->s_srtt += delta) <= 0)
cb->s_srtt = 1;
@@ -474,7 +514,7 @@
cb->s_rttvar = 1;
} else {
/*
- * No rtt measurement yet
+ * No rtt measurement yet.
*/
cb->s_srtt = cb->s_rtt << 3;
cb->s_rttvar = cb->s_rtt << 1;
@@ -485,27 +525,30 @@
((cb->s_srtt >> 2) + cb->s_rttvar) >> 1,
SPXTV_MIN, SPXTV_REXMTMAX);
}
+
/*
- * If all outstanding data is acked, stop retransmit
- * timer and remember to restart (more output or persist).
- * If there is more data to be acked, restart retransmit
- * timer, using current (possibly backed-off) value;
+ * If all outstanding data is acked, stop retransmit timer and
+ * remember to restart (more output or persist). If there is more
+ * data to be acked, restart retransmit timer, using current
+ * (possibly backed-off) value;
*/
if (si->si_ack == cb->s_smax + 1) {
cb->s_timer[SPXT_REXMT] = 0;
cb->s_flags |= SF_RXT;
} else if (cb->s_timer[SPXT_PERSIST] == 0)
cb->s_timer[SPXT_REXMT] = cb->s_rxtcur;
+
/*
- * When new data is acked, open the congestion window.
- * If the window gives us less than ssthresh packets
- * in flight, open exponentially (maxseg at a time).
- * Otherwise open linearly (maxseg^2 / cwnd at a time).
+ * When new data is acked, open the congestion window. If the window
+ * gives us less than ssthresh packets in flight, open exponentially
+ * (maxseg at a time). Otherwise open linearly (maxseg^2 / cwnd at a
+ * time).
*/
incr = CUNIT;
if (cb->s_cwnd > cb->s_ssthresh)
incr = max(incr * incr / cb->s_cwnd, 1);
cb->s_cwnd = min(cb->s_cwnd + incr, cb->s_cwmx);
+
/*
* Trim Acked data from output queue.
*/
@@ -538,9 +581,10 @@
cb->s_smxw = cb->s_swnd;
cb->s_flags |= SF_WIN;
}
+
/*
- * If this packet number is higher than that which
- * we have allocated refuse it, unless urgent
+ * If this packet number is higher than that which we have allocated
+ * refuse it, unless urgent.
*/
if (SSEQ_GT(si->si_seq, cb->s_alo)) {
if (si->si_cc & SPX_SP) {
@@ -561,7 +605,7 @@
* which are then touched by spx_input() after the
* return from spx_reass().
*/
- /*register struct socket *so = cb->s_ipxpcb->ipxp_socket;
+ /*struct socket *so = cb->s_ipxpcb->ipxp_socket;
if (so->so_state && SS_NOFDREF) {
spx_close(cb);
} else
@@ -572,13 +616,14 @@
return (0);
}
}
+
/*
- * If this is a system packet, we don't need to
- * queue it up, and won't update acknowledge #
+ * If this is a system packet, we don't need to queue it up, and
+ * won't update acknowledge #.
*/
- if (si->si_cc & SPX_SP) {
+ if (si->si_cc & SPX_SP)
return (1);
- }
+
/*
* We have already seen this packet, so drop.
*/
@@ -589,9 +634,10 @@
spx_istat.lstdup++;
return (1);
}
+
/*
- * Loop through all packets queued up to insert in
- * appropriate sequence.
+ * Loop through all packets queued up to insert in appropriate
+ * sequence.
*/
for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) {
if (si->si_seq == SI(q)->si_seq) {
@@ -615,10 +661,11 @@
present:
#define SPINC sizeof(struct spxhdr)
SOCKBUF_LOCK(&so->so_rcv);
+
/*
- * Loop through all packets queued up to update acknowledge
- * number, and present all acknowledged data to user;
- * If in packet interface mode, show packet headers.
+ * Loop through all packets queued up to update acknowledge number,
+ * and present all acknowledged data to user; if in packet interface
+ * mode, show packet headers.
*/
for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) {
if (SI(q)->si_seq == cb->s_ack) {
@@ -673,9 +720,9 @@
sbappend_locked(&so->so_rcv, m);
} else
#endif
- if (packetp) {
+ if (packetp)
sbappendrecord_locked(&so->so_rcv, m);
- } else {
+ else {
cb->s_rhdr = *mtod(m, struct spxhdr *);
m->m_data += SPINC;
m->m_len -= SPINC;
@@ -693,46 +740,19 @@
}
void
-spx_ctlinput(cmd, arg_as_sa, dummy)
- int cmd;
- struct sockaddr *arg_as_sa; /* XXX should be swapped with dummy */
- void *dummy;
-{
- caddr_t arg = (/* XXX */ caddr_t)arg_as_sa;
- struct ipx_addr *na;
- struct sockaddr_ipx *sipx;
-
- if (cmd < 0 || cmd >= PRC_NCMDS)
- return;
-
- switch (cmd) {
-
- case PRC_ROUTEDEAD:
- return;
-
- case PRC_IFDOWN:
- case PRC_HOSTDEAD:
- case PRC_HOSTUNREACH:
- sipx = (struct sockaddr_ipx *)arg;
- if (sipx->sipx_family != AF_IPX)
- return;
- na = &sipx->sipx_addr;
- break;
+spx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy)
+{
- default:
- break;
- }
+ /* Currently, nothing. */
}
static int
-spx_output(cb, m0)
- register struct spxpcb *cb;
- struct mbuf *m0;
+spx_output(struct spxpcb *cb, struct mbuf *m0)
{
struct socket *so = cb->s_ipxpcb->ipxp_socket;
- register struct mbuf *m;
- register struct spx *si = NULL;
- register struct sockbuf *sb = &so->so_snd;
+ struct mbuf *m;
+ struct spx *si = NULL;
+ struct sockbuf *sb = &so->so_snd;
int len = 0, win, rcv_win;
short span, off, recordp = 0;
u_short alo;
@@ -747,6 +767,7 @@
if (m0 != NULL) {
int mtu = cb->s_mtu;
int datalen;
+
/*
* Make sure that packet isn't too big.
*/
@@ -767,12 +788,12 @@
cb->s_cc &= ~SPX_EM;
while (len > mtu) {
- /*
- * Here we are only being called
- * from usrreq(), so it is OK to
- * block.
- */
- m = m_copym(m0, 0, mtu, M_TRYWAIT);
+ m = m_copym(m0, 0, mtu, M_DONTWAIT);
+ if (m == NULL) {
+ cb->s_cc |= oldEM;
+ m_freem(m0);
+ return (ENOBUFS);
+ }
if (cb->s_flags & SF_NEWCALL) {
struct mbuf *mm = m;
spx_newchecks[7]++;
@@ -793,6 +814,7 @@
cb->s_cc |= oldEM;
}
}
+
/*
* Force length even, by adding a "garbage byte" if
* necessary.
@@ -813,14 +835,15 @@
m->m_next = m1;
}
}
- m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m == NULL) {
m_freem(m0);
return (ENOBUFS);
}
+
/*
- * Fill in mbuf with extended SP header
- * and addresses and length put into network format.
+ * Fill in mbuf with extended SP header and addresses and
+ * length put into network format.
*/
MH_ALIGN(m, sizeof(struct spx));
m->m_len = sizeof(struct spx);
@@ -829,7 +852,7 @@
si->si_i = *cb->s_ipx;
si->si_s = cb->s_shdr;
if ((cb->s_flags & SF_PI) && (cb->s_flags & SF_HO)) {
- register struct spxhdr *sh;
+ struct spxhdr *sh;
if (m0->m_len < sizeof(*sh)) {
if((m0 = m_pullup(m0, sizeof(*sh))) == NULL) {
m_free(m);
@@ -852,12 +875,11 @@
}
if (cb->s_oobflags & SF_SOOB) {
/*
- * Per jqj at cornell:
- * make sure OB packets convey exactly 1 byte.
- * If the packet is 1 byte or larger, we
- * have already guaranted there to be at least
- * one garbage byte for the checksum, and
- * extra bytes shouldn't hurt!
+ * Per jqj at cornell: Make sure OB packets convey
+ * exactly 1 byte. If the packet is 1 byte or
+ * larger, we have already guaranted there to be at
+ * least one garbage byte for the checksum, and extra
+ * bytes shouldn't hurt!
*/
if (len > sizeof(*si)) {
si->si_cc |= SPX_OB;
@@ -866,8 +888,9 @@
}
si->si_len = htons((u_short)len);
m->m_pkthdr.len = ((len - 1) | 1) + 1;
+
/*
- * queue stuff up for output
+ * Queue stuff up for output.
*/
sbappendrecord(sb, m);
cb->s_seq++;
@@ -881,10 +904,9 @@
win = min(cb->s_swnd, (cb->s_cwnd / CUNIT));
/*
- * If in persist timeout with window of 0, send a probe.
- * Otherwise, if window is small but nonzero
- * and timer expired, send what we can and go into
- * transmit state.
+ * If in persist timeout with window of 0, send a probe. Otherwise,
+ * if window is small but nonzero and timer expired, send what we can
+ * and go into transmit state.
*/
if (cb->s_force == 1 + SPXT_PERSIST) {
if (win != 0) {
@@ -897,12 +919,10 @@
if (len < 0) {
/*
- * Window shrank after we went into it.
- * If window shrank to 0, cancel pending
- * restransmission and pull s_snxt back
- * to (closed) window. We will enter persist
- * state below. If the widndow didn't close completely,
- * just wait for an ACK.
+ * Window shrank after we went into it. If window shrank to
+ * 0, cancel pending restransmission and pull s_snxt back to
+ * (closed) window. We will enter persist state below. If
+ * the widndow didn't close completely, just wait for an ACK.
*/
len = 0;
if (win == 0) {
@@ -919,7 +939,7 @@
*/
if (cb->s_oobflags & SF_SOOB) {
/*
- * must transmit this out of band packet
+ * Must transmit this out of band packet.
*/
cb->s_oobflags &= ~ SF_SOOB;
sendalot = 1;
@@ -930,18 +950,18 @@
goto send;
if (cb->s_state < TCPS_ESTABLISHED)
goto send;
+
/*
- * Silly window can't happen in spx.
- * Code from tcp deleted.
+ * Silly window can't happen in spx. Code from TCP deleted.
*/
if (len)
goto send;
+
/*
- * Compare available window to amount of window
- * known to peer (as advertised window less
- * next expected input.) If the difference is at least two
- * packets or at least 35% of the mximum possible window,
- * then want to send a window update to peer.
+ * Compare available window to amount of window known to peer (as
+ * advertised window less next expected input.) If the difference is
+ * at least two packets or at least 35% of the mximum possible
+ * window, then want to send a window update to peer.
*/
if (rcv_win > 0) {
u_short delta = 1 + cb->s_alo - cb->s_ack;
@@ -955,20 +975,20 @@
}
}
+
/*
- * Many comments from tcp_output.c are appropriate here
- * including . . .
+ * Many comments from tcp_output.c are appropriate here including ...
* If send window is too small, there is data to transmit, and no
- * retransmit or persist is pending, then go to persist state.
- * If nothing happens soon, send when timer expires:
- * if window is nonzero, transmit what we can,
- * otherwise send a probe.
+ * retransmit or persist is pending, then go to persist state. If
+ * nothing happens soon, send when timer expires: if window is
+ * nonzero, transmit what we can, otherwise send a probe.
*/
if (so->so_snd.sb_cc && cb->s_timer[SPXT_REXMT] == 0 &&
- cb->s_timer[SPXT_PERSIST] == 0) {
- cb->s_rxtshift = 0;
- spx_setpersist(cb);
+ cb->s_timer[SPXT_PERSIST] == 0) {
+ cb->s_rxtshift = 0;
+ spx_setpersist(cb);
}
+
/*
* No reason to send a packet, just return.
*/
@@ -995,8 +1015,9 @@
spxstat.spxs_sndvoid++, si = 0;
}
}
+
/*
- * update window
+ * Update window.
*/
if (rcv_win < 0)
rcv_win = 0;
@@ -1006,13 +1027,12 @@
if (si != NULL) {
/*
- * must make a copy of this packet for
- * ipx_output to monkey with
+ * Must make a copy of this packet for ipx_output to monkey
+ * with.
*/
m = m_copy(dtom(si), 0, (int)M_COPYALL);
- if (m == NULL) {
+ if (m == NULL)
return (ENOBUFS);
- }
si = mtod(m, struct spx *);
if (SSEQ_LT(si->si_seq, cb->s_smax))
spxstat.spxs_sndrexmitpack++;
@@ -1020,18 +1040,19 @@
spxstat.spxs_sndpack++;
} else if (cb->s_force || cb->s_flags & SF_ACKNOW) {
/*
- * Must send an acknowledgement or a probe
+ * Must send an acknowledgement or a probe.
*/
if (cb->s_force)
spxstat.spxs_sndprobe++;
if (cb->s_flags & SF_ACKNOW)
spxstat.spxs_sndacks++;
- m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m == NULL)
return (ENOBUFS);
+
/*
- * Fill in mbuf with extended SP header
- * and addresses and length put into network format.
+ * Fill in mbuf with extended SP header and addresses and
+ * length put into network format.
*/
MH_ALIGN(m, sizeof(struct spx));
m->m_len = sizeof(*si);
@@ -1066,12 +1087,13 @@
cb->s_rtt = 1;
}
}
+
/*
- * Set rexmt timer if not currently set,
- * Initial value for retransmit timer is smoothed
- * round-trip time + 2 * round-trip time variance.
- * Initialize shift counter which is used for backoff
- * of retransmit time.
+ * Set rexmt timer if not currently set, initial
+ * value for retransmit timer is smoothed round-trip
+ * time + 2 * round-trip time variance. Initialize
+ * shift counter which is used for backoff of
+ * retransmit time.
*/
if (cb->s_timer[SPXT_REXMT] == 0 &&
cb->s_snxt != cb->s_rack) {
@@ -1081,49 +1103,46 @@
cb->s_rxtshift = 0;
}
}
- } else if (SSEQ_LT(cb->s_smax, si->si_seq)) {
+ } else if (SSEQ_LT(cb->s_smax, si->si_seq))
cb->s_smax = si->si_seq;
- }
} else if (cb->s_state < TCPS_ESTABLISHED) {
if (cb->s_rtt == 0)
cb->s_rtt = 1; /* Time initial handshake */
if (cb->s_timer[SPXT_REXMT] == 0)
cb->s_timer[SPXT_REXMT] = cb->s_rxtcur;
}
- {
- /*
- * Do not request acks when we ack their data packets or
- * when we do a gratuitous window update.
- */
- if (((si->si_cc & SPX_SP) == 0) || cb->s_force)
- si->si_cc |= SPX_SA;
- si->si_seq = htons(si->si_seq);
- si->si_alo = htons(alo);
- si->si_ack = htons(cb->s_ack);
- if (ipxcksum) {
- si->si_sum = ipx_cksum(m, ntohs(si->si_len));
- } else
- si->si_sum = 0xffff;
+ /*
+ * Do not request acks when we ack their data packets or when we do a
+ * gratuitous window update.
+ */
+ if (((si->si_cc & SPX_SP) == 0) || cb->s_force)
+ si->si_cc |= SPX_SA;
+ si->si_seq = htons(si->si_seq);
+ si->si_alo = htons(alo);
+ si->si_ack = htons(cb->s_ack);
- cb->s_outx = 4;
- if (so->so_options & SO_DEBUG || traceallspxs)
- spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0);
+ if (ipxcksum)
+ si->si_sum = ipx_cksum(m, ntohs(si->si_len));
+ else
+ si->si_sum = 0xffff;
- if (so->so_options & SO_DONTROUTE)
- error = ipx_outputfl(m, NULL, IPX_ROUTETOIF);
- else
- error = ipx_outputfl(m, &cb->s_ipxpcb->ipxp_route, 0);
- }
- if (error) {
+ cb->s_outx = 4;
+ if (so->so_options & SO_DEBUG || traceallspxs)
+ spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0);
+
+ if (so->so_options & SO_DONTROUTE)
+ error = ipx_outputfl(m, NULL, IPX_ROUTETOIF);
+ else
+ error = ipx_outputfl(m, &cb->s_ipxpcb->ipxp_route, 0);
+ if (error)
return (error);
- }
spxstat.spxs_sndtotal++;
+
/*
- * Data sent (as far as we can tell).
- * If this advertises a larger window than any other segment,
- * then remember the size of the advertized window.
- * Any pending ACK has now been sent.
+ * Data sent (as far as we can tell). If this advertises a larger
+ * window than any other segment, then remember the size of the
+ * advertized window. Any pending ACK has now been sent.
*/
cb->s_force = 0;
cb->s_flags &= ~(SF_ACKNOW|SF_DELACK);
@@ -1138,15 +1157,15 @@
static int spx_do_persist_panics = 0;
static void
-spx_setpersist(cb)
- register struct spxpcb *cb;
+spx_setpersist(struct spxpcb *cb)
{
- register int t = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1;
+ int t = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1;
IPX_LOCK_ASSERT(cb->s_ipxpcb);
if (cb->s_timer[SPXT_REXMT] && spx_do_persist_panics)
panic("spx_output REXMT");
+
/*
* Start/restart persistance timer.
*/
@@ -1158,29 +1177,37 @@
}
int
-spx_ctloutput(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
+spx_ctloutput(struct socket *so, struct sockopt *sopt)
{
- struct ipxpcb *ipxp = sotoipxpcb(so);
- register struct spxpcb *cb;
+ struct spxhdr spxhdr;
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
int mask, error;
short soptval;
u_short usoptval;
int optval;
- error = 0;
+ ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_ctloutput: ipxp == NULL"));
- if (sopt->sopt_level != IPXPROTO_SPX) {
- /* This will have to be changed when we do more general
- stacking of protocols */
+ /*
+ * This will have to be changed when we do more general stacking of
+ * protocols.
+ */
+ if (sopt->sopt_level != IPXPROTO_SPX)
return (ipx_ctloutput(so, sopt));
+
+ IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ IPX_UNLOCK(ipxp);
+ return (ECONNRESET);
}
- if (ipxp == NULL)
- return (EINVAL);
- else
- cb = ipxtospxpcb(ipxp);
+ IPX_LOCK(ipxp);
+ cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_ctloutput: cb == NULL"));
+
+ error = 0;
switch (sopt->sopt_dir) {
case SOPT_GET:
switch (sopt->sopt_name) {
@@ -1191,38 +1218,47 @@
case SO_HEADERS_ON_OUTPUT:
mask = SF_HO;
get_flags:
- /* Unlocked read. */
soptval = cb->s_flags & mask;
- error = sooptcopyout(sopt, &soptval, sizeof soptval);
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &soptval,
+ sizeof(soptval));
break;
case SO_MTU:
- /* Unlocked read. */
usoptval = cb->s_mtu;
- error = sooptcopyout(sopt, &usoptval, sizeof usoptval);
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &usoptval,
+ sizeof(usoptval));
break;
case SO_LAST_HEADER:
- /* Unlocked read. */
- error = sooptcopyout(sopt, &cb->s_rhdr,
- sizeof cb->s_rhdr);
+ spxhdr = cb->s_rhdr;
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr));
break;
case SO_DEFAULT_HEADERS:
- /* Unlocked read. */
- error = sooptcopyout(sopt, &cb->s_shdr,
- sizeof cb->s_shdr);
+ spxhdr = cb->s_shdr;
+ IPX_UNLOCK(ipxp);
+ error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr));
break;
default:
+ IPX_UNLOCK(ipxp);
error = ENOPROTOOPT;
}
break;
case SOPT_SET:
+ /*
+ * XXX Why are these shorts on get and ints on set? That
+ * doesn't make any sense...
+ *
+ * XXXRW: Note, when we re-acquire the ipxp lock, we should
+ * re-check that it's not dropped.
+ */
+ IPX_UNLOCK(ipxp);
switch (sopt->sopt_name) {
- /* XXX why are these shorts on get and ints on set?
- that doesn't make any sense... */
case SO_HEADERS_ON_INPUT:
mask = SF_HI;
goto set_head;
@@ -1291,41 +1327,45 @@
error = ENOPROTOOPT;
}
break;
+
+ default:
+ panic("spx_ctloutput: bad socket option direction");
}
return (error);
}
-static int
-spx_usr_abort(so)
- struct socket *so;
+static void
+spx_usr_abort(struct socket *so)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_usr_abort: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_usr_abort: cb == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
spx_drop(cb, ECONNABORTED);
+ IPX_UNLOCK(ipxp);
IPX_LIST_UNLOCK();
- return (0);
}
/*
- * Accept a connection. Essentially all the work is
- * done at higher levels; just return the address
- * of the peer, storing through addr.
+ * Accept a connection. Essentially all the work is done at higher levels;
+ * just return the address of the peer, storing through addr.
*/
static int
-spx_accept(so, nam)
- struct socket *so;
- struct sockaddr **nam;
+spx_accept(struct socket *so, struct sockaddr **nam)
{
struct ipxpcb *ipxp;
struct sockaddr_ipx *sipx, ssipx;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_accept: ipxp == NULL"));
+
sipx = &ssipx;
bzero(sipx, sizeof *sipx);
sipx->sipx_len = sizeof *sipx;
@@ -1338,10 +1378,7 @@
}
static int
-spx_attach(so, proto, td)
- struct socket *so;
- int proto;
- struct thread *td;
+spx_attach(struct socket *so, int proto, struct thread *td)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
@@ -1350,35 +1387,34 @@
int error;
ipxp = sotoipxpcb(so);
- cb = ipxtospxpcb(ipxp);
+ KASSERT(ipxp == NULL, ("spx_attach: ipxp != NULL"));
- if (ipxp != NULL)
- return (EISCONN);
- IPX_LIST_LOCK();
- error = ipx_pcballoc(so, &ipxpcb_list, td);
- if (error)
- goto spx_attach_end;
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
error = soreserve(so, (u_long) 3072, (u_long) 3072);
if (error)
- goto spx_attach_end;
+ return (error);
}
- ipxp = sotoipxpcb(so);
MALLOC(cb, struct spxpcb *, sizeof *cb, M_PCB, M_NOWAIT | M_ZERO);
-
- if (cb == NULL) {
- error = ENOBUFS;
- goto spx_attach_end;
+ if (cb == NULL)
+ return (ENOBUFS);
+ mm = m_getclr(M_DONTWAIT, MT_DATA);
+ if (mm == NULL) {
+ FREE(cb, M_PCB);
+ return (ENOBUFS);
}
- sb = &so->so_snd;
- mm = m_getclr(M_DONTWAIT, MT_HEADER);
- if (mm == NULL) {
+ IPX_LIST_LOCK();
+ error = ipx_pcballoc(so, &ipxpcb_list, td);
+ if (error) {
+ IPX_LIST_UNLOCK();
+ m_free(mm);
FREE(cb, M_PCB);
- error = ENOBUFS;
- goto spx_attach_end;
+ return (error);
}
+ ipxp = sotoipxpcb(so);
+ ipxp->ipxp_flags |= IPXP_SPX;
+
cb->s_ipx = mtod(mm, struct ipx *);
cb->s_state = TCPS_LISTEN;
cb->s_smax = -1;
@@ -1386,62 +1422,116 @@
cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
cb->s_ipxpcb = ipxp;
cb->s_mtu = 576 - sizeof(struct spx);
+ sb = &so->so_snd;
cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
cb->s_ssthresh = cb->s_cwnd;
cb->s_cwmx = sbspace(sb) * CUNIT / (2 * sizeof(struct spx));
- /* Above is recomputed when connecting to account
- for changed buffering or mtu's */
+ /*
+ * Above is recomputed when connecting to account for changed
+ * buffering or mtu's.
+ */
cb->s_rtt = SPXTV_SRTTBASE;
cb->s_rttvar = SPXTV_SRTTDFLT << 2;
SPXT_RANGESET(cb->s_rxtcur,
((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1,
SPXTV_MIN, SPXTV_REXMTMAX);
ipxp->ipxp_pcb = (caddr_t)cb;
-spx_attach_end:
IPX_LIST_UNLOCK();
- return (error);
+ return (0);
+}
+
+static void
+spx_pcbdetach(struct ipxpcb *ipxp)
+{
+ struct spxpcb *cb;
+ struct spx_q *s;
+ struct mbuf *m;
+
+ IPX_LOCK_ASSERT(ipxp);
+
+ cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_pcbdetach: cb == NULL"));
+
+ s = cb->s_q.si_next;
+ while (s != &(cb->s_q)) {
+ s = s->si_next;
+ remque(s);
+ m = dtom(s);
+ m_freem(m);
+ }
+ m_free(dtom(cb->s_ipx));
+ FREE(cb, M_PCB);
+ ipxp->ipxp_pcb = NULL;
}
static int
-spx_bind(so, nam, td)
- struct socket *so;
- struct sockaddr *nam;
- struct thread *td;
+spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct ipxpcb *ipxp;
int error;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_bind: ipxp == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = EINVAL;
+ goto out;
+ }
error = ipx_pcbbind(ipxp, nam, td);
+out:
IPX_UNLOCK(ipxp);
IPX_LIST_UNLOCK();
return (error);
}
+static void
+spx_usr_close(struct socket *so)
+{
+ struct ipxpcb *ipxp;
+ struct spxpcb *cb;
+
+ ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_usr_close: ipxp == NULL"));
+
+ cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_usr_close: cb == NULL"));
+
+ IPX_LIST_LOCK();
+ IPX_LOCK(ipxp);
+ if (cb->s_state > TCPS_LISTEN)
+ spx_disconnect(cb);
+ else
+ spx_close(cb);
+ IPX_UNLOCK(ipxp);
+ IPX_LIST_UNLOCK();
+}
+
/*
- * Initiate connection to peer.
- * Enter SYN_SENT state, and mark socket as connecting.
- * Start keep-alive timer, setup prototype header,
- * Send initial system packet requesting connection.
+ * Initiate connection to peer. Enter SYN_SENT state, and mark socket as
+ * connecting. Start keep-alive timer, setup prototype header, send initial
+ * system packet requesting connection.
*/
static int
-spx_connect(so, nam, td)
- struct socket *so;
- struct sockaddr *nam;
- struct thread *td;
+spx_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
int error;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_connect: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_connect: cb == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = EINVAL;
+ goto spx_connect_end;
+ }
if (ipxp->ipxp_lport == 0) {
error = ipx_pcbbind(ipxp, NULL, td);
if (error)
@@ -1458,11 +1548,9 @@
cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
cb->s_force = 1 + SPXTV_KEEP;
/*
- * Other party is required to respond to
- * the port I send from, but he is not
- * required to answer from where I am sending to,
- * so allow wildcarding.
- * original port I am sending to is still saved in
+ * Other party is required to respond to the port I send from, but he
+ * is not required to answer from where I am sending to, so allow
+ * wildcarding. Original port I am sending to is still saved in
* cb->s_dport.
*/
ipxp->ipxp_fport = 0;
@@ -1473,54 +1561,61 @@
return (error);
}
-static int
-spx_detach(so)
- struct socket *so;
+static void
+spx_detach(struct socket *so)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
+ /*
+ * XXXRW: Should assert appropriately detached.
+ */
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_detach: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_detach: cb == NULL"));
- if (ipxp == NULL)
- return (ENOTCONN);
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
- if (cb->s_state > TCPS_LISTEN)
- spx_disconnect(cb);
- else
- spx_close(cb);
+ spx_pcbdetach(ipxp);
+ ipx_pcbfree(ipxp);
IPX_LIST_UNLOCK();
- return (0);
}
/*
- * We may decide later to implement connection closing
- * handshaking at the spx level optionally.
- * here is the hook to do it:
+ * We may decide later to implement connection closing handshaking at the spx
+ * level optionally. Here is the hook to do it:
*/
static int
-spx_usr_disconnect(so)
- struct socket *so;
+spx_usr_disconnect(struct socket *so)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
+ int error;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_usr_disconnect: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_usr_disconnect: cb == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = EINVAL;
+ goto out;
+ }
spx_disconnect(cb);
+ error = 0;
+out:
+ IPX_UNLOCK(ipxp);
IPX_LIST_UNLOCK();
- return (0);
+ return (error);
}
static int
-spx_listen(so, td)
- struct socket *so;
- struct thread *td;
+spx_listen(struct socket *so, int backlog, struct thread *td)
{
int error;
struct ipxpcb *ipxp;
@@ -1528,90 +1623,116 @@
error = 0;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_listen: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_listen: cb == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = EINVAL;
+ goto out;
+ }
SOCK_LOCK(so);
error = solisten_proto_check(so);
if (error == 0 && ipxp->ipxp_lport == 0)
error = ipx_pcbbind(ipxp, NULL, td);
if (error == 0) {
cb->s_state = TCPS_LISTEN;
- solisten_proto(so);
+ solisten_proto(so, backlog);
}
SOCK_UNLOCK(so);
+out:
IPX_UNLOCK(ipxp);
IPX_LIST_UNLOCK();
return (error);
}
/*
- * After a receive, possibly send acknowledgment
- * updating allocation.
+ * After a receive, possibly send acknowledgment updating allocation.
*/
static int
-spx_rcvd(so, flags)
- struct socket *so;
- int flags;
+spx_rcvd(struct socket *so, int flags)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
+ int error;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_rcvd: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_rcvd: cb == NULL"));
IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = EINVAL;
+ goto out;
+ }
cb->s_flags |= SF_RVD;
spx_output(cb, NULL);
cb->s_flags &= ~SF_RVD;
+ error = 0;
+out:
IPX_UNLOCK(ipxp);
- return (0);
+ return (error);
}
static int
-spx_rcvoob(so, m, flags)
- struct socket *so;
- struct mbuf *m;
- int flags;
+spx_rcvoob(struct socket *so, struct mbuf *m, int flags)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
+ int error;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_rcvoob: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_rcvoob: cb == NULL"));
+ IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = EINVAL;
+ goto out;
+ }
SOCKBUF_LOCK(&so->so_rcv);
if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark ||
(so->so_rcv.sb_state & SBS_RCVATMARK)) {
SOCKBUF_UNLOCK(&so->so_rcv);
m->m_len = 1;
- /* Unlocked read. */
*mtod(m, caddr_t) = cb->s_iobc;
- return (0);
+ error = 0;
+ goto out;
}
SOCKBUF_UNLOCK(&so->so_rcv);
- return (EINVAL);
+ error = EINVAL;
+out:
+ IPX_UNLOCK(ipxp);
+ return (error);
}
static int
-spx_send(so, flags, m, addr, controlp, td)
- struct socket *so;
- int flags;
- struct mbuf *m;
- struct sockaddr *addr;
- struct mbuf *controlp;
- struct thread *td;
+spx_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
+ struct mbuf *controlp, struct thread *td)
{
- int error;
struct ipxpcb *ipxp;
struct spxpcb *cb;
+ int error;
- error = 0;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_send: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_send: cb == NULL"));
+ error = 0;
IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = ECONNRESET;
+ goto spx_send_end;
+ }
if (flags & PRUS_OOB) {
if (sbspace(&so->so_snd) < -512) {
error = ENOBUFS;
@@ -1641,114 +1762,116 @@
}
static int
-spx_shutdown(so)
- struct socket *so;
+spx_shutdown(struct socket *so)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
+ int error;
ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_shutdown: ipxp == NULL"));
+
cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_shutdown: cb == NULL"));
socantsendmore(so);
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
+ if (ipxp->ipxp_flags & IPXP_DROPPED) {
+ error = EINVAL;
+ goto out;
+ }
spx_usrclosed(cb);
+ error = 0;
+out:
+ IPX_UNLOCK(ipxp);
IPX_LIST_UNLOCK();
- return (0);
+ return (error);
}
static int
-spx_sp_attach(so, proto, td)
- struct socket *so;
- int proto;
- struct thread *td;
+spx_sp_attach(struct socket *so, int proto, struct thread *td)
{
- int error;
struct ipxpcb *ipxp;
+ struct spxpcb *cb;
+ int error;
+
+ KASSERT(so->so_pcb == NULL, ("spx_sp_attach: so_pcb != NULL"));
error = spx_attach(so, proto, td);
- if (error == 0) {
- ipxp = sotoipxpcb(so);
- ((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |=
- (SF_HI | SF_HO | SF_PI);
- }
- return (error);
+ if (error)
+ return (error);
+
+ ipxp = sotoipxpcb(so);
+ KASSERT(ipxp != NULL, ("spx_sp_attach: ipxp == NULL"));
+
+ cb = ipxtospxpcb(ipxp);
+ KASSERT(cb != NULL, ("spx_sp_attach: cb == NULL"));
+
+ IPX_LOCK(ipxp);
+ cb->s_flags |= (SF_HI | SF_HO | SF_PI);
+ IPX_UNLOCK(ipxp);
+ return (0);
}
/*
- * Create template to be used to send spx packets on a connection.
- * Called after host entry created, fills
- * in a skeletal spx header (choosing connection id),
- * minimizing the amount of work necessary when the connection is used.
+ * Create template to be used to send spx packets on a connection. Called
+ * after host entry created, fills in a skeletal spx header (choosing
+ * connection id), minimizing the amount of work necessary when the
+ * connection is used.
*/
static void
-spx_template(cb)
- register struct spxpcb *cb;
+spx_template(struct spxpcb *cb)
{
- register struct ipxpcb *ipxp = cb->s_ipxpcb;
- register struct ipx *ipx = cb->s_ipx;
- register struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd);
+ struct ipxpcb *ipxp = cb->s_ipxpcb;
+ struct ipx *ipx = cb->s_ipx;
+ struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd);
IPX_LOCK_ASSERT(ipxp);
ipx->ipx_pt = IPXPROTO_SPX;
ipx->ipx_sna = ipxp->ipxp_laddr;
ipx->ipx_dna = ipxp->ipxp_faddr;
+ SPX_LOCK();
cb->s_sid = htons(spx_iss);
spx_iss += SPX_ISSINCR/2;
+ SPX_UNLOCK();
cb->s_alo = 1;
cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu;
- cb->s_ssthresh = cb->s_cwnd; /* Try to expand fast to full complement
- of large packets */
+ /* Try to expand fast to full complement of large packets. */
+ cb->s_ssthresh = cb->s_cwnd;
cb->s_cwmx = (sbspace(sb) * CUNIT) / (2 * sizeof(struct spx));
+ /* But allow for lots of little packets as well. */
cb->s_cwmx = max(cb->s_cwmx, cb->s_cwnd);
- /* But allow for lots of little packets as well */
}
/*
- * Close a SPIP control block:
- * discard spx control block itself
- * discard ipx protocol control block
- * wake up any sleepers
- * cb will always be invalid after this call.
+ * Close a SPIP control block. Wake up any sleepers. We used to free any
+ * queued packets and cb->s_ipx here, but now we defer that until the pcb is
+ * discarded.
*/
void
-spx_close(cb)
- register struct spxpcb *cb;
+spx_close(struct spxpcb *cb)
{
- register struct spx_q *s;
struct ipxpcb *ipxp = cb->s_ipxpcb;
struct socket *so = ipxp->ipxp_socket;
- register struct mbuf *m;
+ KASSERT(ipxp != NULL, ("spx_close: ipxp == NULL"));
IPX_LIST_LOCK_ASSERT();
IPX_LOCK_ASSERT(ipxp);
- s = cb->s_q.si_next;
- while (s != &(cb->s_q)) {
- s = s->si_next;
- m = dtom(s->si_prev);
- remque(s->si_prev);
- m_freem(m);
- }
- m_free(dtom(cb->s_ipx));
- FREE(cb, M_PCB);
- ipxp->ipxp_pcb = NULL;
+ ipxp->ipxp_flags |= IPXP_DROPPED;
soisdisconnected(so);
- ipx_pcbdetach(ipxp);
spxstat.spxs_closed++;
}
/*
- * Someday we may do level 3 handshaking
- * to close a connection or send a xerox style error.
- * For now, just close.
- * cb will always be invalid after this call.
+ * Someday we may do level 3 handshaking to close a connection or send a
+ * xerox style error. For now, just close. cb will always be invalid after
+ * this call.
*/
static void
-spx_usrclosed(cb)
- register struct spxpcb *cb;
+spx_usrclosed(struct spxpcb *cb)
{
IPX_LIST_LOCK_ASSERT();
@@ -1761,8 +1884,7 @@
* cb will always be invalid after this call.
*/
static void
-spx_disconnect(cb)
- register struct spxpcb *cb;
+spx_disconnect(struct spxpcb *cb)
{
IPX_LIST_LOCK_ASSERT();
@@ -1772,14 +1894,11 @@
}
/*
- * Drop connection, reporting
- * the specified error.
- * cb will always be invalid after this call.
+ * Drop connection, reporting the specified error. cb will always be invalid
+ * after this call.
*/
static void
-spx_drop(cb, errno)
- register struct spxpcb *cb;
- int errno;
+spx_drop(struct spxpcb *cb, int errno)
{
struct socket *so = cb->s_ipxpcb->ipxp_socket;
@@ -1787,9 +1906,8 @@
IPX_LOCK_ASSERT(cb->s_ipxpcb);
/*
- * someday, in the xerox world
- * we will generate error protocol packets
- * announcing that the socket has gone away.
+ * Someday, in the xerox world we will generate error protocol
+ * packets announcing that the socket has gone away.
*/
if (TCPS_HAVERCVDSYN(cb->s_state)) {
spxstat.spxs_drops++;
@@ -1802,10 +1920,10 @@
}
/*
- * Fast timeout routine for processing delayed acks
+ * Fast timeout routine for processing delayed acks.
*/
void
-spx_fasttimo()
+spx_fasttimo(void)
{
struct ipxpcb *ipxp;
struct spxpcb *cb;
@@ -1813,8 +1931,13 @@
IPX_LIST_LOCK();
LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) {
IPX_LOCK(ipxp);
- if ((cb = (struct spxpcb *)ipxp->ipxp_pcb) != NULL &&
- (cb->s_flags & SF_DELACK)) {
+ if (!(ipxp->ipxp_flags & IPXP_SPX) ||
+ (ipxp->ipxp_flags & IPXP_DROPPED)) {
+ IPX_UNLOCK(ipxp);
+ continue;
+ }
+ cb = ipxtospxpcb(ipxp);
+ if (cb->s_flags & SF_DELACK) {
cb->s_flags &= ~SF_DELACK;
cb->s_flags |= SF_ACKNOW;
spxstat.spxs_delack++;
@@ -1826,59 +1949,56 @@
}
/*
- * spx protocol timeout routine called every 500 ms.
- * Updates the timers in all active pcb's and
- * causes finite state machine actions if timers expire.
+ * spx protocol timeout routine called every 500 ms. Updates the timers in
+ * all active pcb's and causes finite state machine actions if timers expire.
*/
void
-spx_slowtimo()
+spx_slowtimo(void)
{
- struct ipxpcb *ip, *ip_temp;
+ struct ipxpcb *ipxp;
struct spxpcb *cb;
int i;
/*
- * Search through tcb's and update active timers. Note that timers
- * may free the ipxpcb, so be sure to handle that case.
- *
- * spx_timers() may remove an ipxpcb entry, so we have to be ready to
- * continue despite that. The logic here is a bit obfuscated.
+ * Search through tcb's and update active timers. Once, timers could
+ * free ipxp's, but now we do that only when detaching a socket.
*/
IPX_LIST_LOCK();
- LIST_FOREACH_SAFE(ip, &ipxpcb_list, ipxp_list, ip_temp) {
- cb = ipxtospxpcb(ip);
- if (cb == NULL)
+ LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) {
+ IPX_LOCK(ipxp);
+ if (!(ipxp->ipxp_flags & IPXP_SPX) ||
+ (ipxp->ipxp_flags & IPXP_DROPPED)) {
+ IPX_UNLOCK(ipxp);
continue;
- IPX_LOCK(cb->s_ipxpcb);
+ }
+
+ cb = (struct spxpcb *)ipxp->ipxp_pcb;
+ KASSERT(cb != NULL, ("spx_slowtimo: cb == NULL"));
for (i = 0; i < SPXT_NTIMERS; i++) {
if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
- /*
- * spx_timers() returns (NULL) if it free'd
- * the pcb.
- */
- cb = spx_timers(cb, i);
- if (cb == NULL)
+ spx_timers(cb, i);
+ if (ipxp->ipxp_flags & IPXP_DROPPED)
break;
}
}
- if (cb != NULL) {
+ if (!(ipxp->ipxp_flags & IPXP_DROPPED)) {
cb->s_idle++;
if (cb->s_rtt)
cb->s_rtt++;
- IPX_UNLOCK(cb->s_ipxpcb);
}
+ IPX_UNLOCK(ipxp);
}
- spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */
IPX_LIST_UNLOCK();
+ SPX_LOCK();
+ spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */
+ SPX_UNLOCK();
}
/*
* SPX timer processing.
*/
-static struct spxpcb *
-spx_timers(cb, timer)
- register struct spxpcb *cb;
- int timer;
+static void
+spx_timers(struct spxpcb *cb, int timer)
{
long rexmt;
int win;
@@ -1888,27 +2008,25 @@
cb->s_force = 1 + timer;
switch (timer) {
-
- /*
- * 2 MSL timeout in shutdown went off. TCP deletes connection
- * control block.
- */
case SPXT_2MSL:
+ /*
+ * 2 MSL timeout in shutdown went off. TCP deletes
+ * connection control block.
+ */
printf("spx: SPXT_2MSL went off for no reason\n");
cb->s_timer[timer] = 0;
break;
- /*
- * Retransmission timer went off. Message has not
- * been acked within retransmit interval. Back off
- * to a longer retransmit interval and retransmit one packet.
- */
case SPXT_REXMT:
+ /*
+ * Retransmission timer went off. Message has not been acked
+ * within retransmit interval. Back off to a longer
+ * retransmit interval and retransmit one packet.
+ */
if (++cb->s_rxtshift > SPX_MAXRXTSHIFT) {
cb->s_rxtshift = SPX_MAXRXTSHIFT;
spxstat.spxs_timeoutdrop++;
spx_drop(cb, ETIMEDOUT);
- cb = NULL;
break;
}
spxstat.spxs_rexmttimeo++;
@@ -1916,25 +2034,27 @@
rexmt *= spx_backoff[cb->s_rxtshift];
SPXT_RANGESET(cb->s_rxtcur, rexmt, SPXTV_MIN, SPXTV_REXMTMAX);
cb->s_timer[SPXT_REXMT] = cb->s_rxtcur;
+
/*
- * If we have backed off fairly far, our srtt
- * estimate is probably bogus. Clobber it
- * so we'll take the next rtt measurement as our srtt;
- * move the current srtt into rttvar to keep the current
- * retransmit times until then.
+ * If we have backed off fairly far, our srtt estimate is
+ * probably bogus. Clobber it so we'll take the next rtt
+ * measurement as our srtt; move the current srtt into rttvar
+ * to keep the current retransmit times until then.
*/
if (cb->s_rxtshift > SPX_MAXRXTSHIFT / 4 ) {
cb->s_rttvar += (cb->s_srtt >> 2);
cb->s_srtt = 0;
}
cb->s_snxt = cb->s_rack;
+
/*
* If timing a packet, stop the timer.
*/
cb->s_rtt = 0;
+
/*
* See very long discussion in tcp_timer.c about congestion
- * window and sstrhesh
+ * window and sstrhesh.
*/
win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2;
if (win < 2)
@@ -1944,21 +2064,21 @@
spx_output(cb, NULL);
break;
- /*
- * Persistance timer into zero window.
- * Force a probe to be sent.
- */
case SPXT_PERSIST:
+ /*
+ * Persistance timer into zero window. Force a probe to be
+ * sent.
+ */
spxstat.spxs_persisttimeo++;
spx_setpersist(cb);
spx_output(cb, NULL);
break;
- /*
- * Keep-alive timer went off; send something
- * or drop connection if idle for too long.
- */
case SPXT_KEEP:
+ /*
+ * Keep-alive timer went off; send something or drop
+ * connection if idle for too long.
+ */
spxstat.spxs_keeptimeo++;
if (cb->s_state < TCPS_ESTABLISHED)
goto dropit;
@@ -1971,11 +2091,13 @@
cb->s_idle = 0;
cb->s_timer[SPXT_KEEP] = SPXTV_KEEP;
break;
+
dropit:
spxstat.spxs_keepdrops++;
spx_drop(cb, ETIMEDOUT);
- cb = NULL;
break;
+
+ default:
+ panic("spx_timers: unknown timer %d", timer);
}
- return (cb);
}
Index: ipx_var.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_var.h -L sys/netipx/ipx_var.h -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_var.h
+++ sys/netipx/ipx_var.h
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -33,7 +58,7 @@
*
* @(#)ipx_var.h
*
- * $FreeBSD: src/sys/netipx/ipx_var.h,v 1.22 2005/01/07 01:45:47 imp Exp $
+ * $FreeBSD: src/sys/netipx/ipx_var.h,v 1.24 2007/05/11 10:38:34 rwatson Exp $
*/
#ifndef _NETIPX_IPX_VAR_H_
@@ -88,7 +113,7 @@
u_short ipx_cksum(struct mbuf *m, int len);
int ipx_control(struct socket *so, u_long cmd, caddr_t data,
- struct ifnet *ifp, struct thread *td);
+ struct ifnet *ifp, struct thread *td);
void ipx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy);
int ipx_ctloutput(struct socket *so, struct sockopt *sopt);
void ipx_drop(struct ipxpcb *ipxp, int errno);
Index: ipx_pcb.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_pcb.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_pcb.h -L sys/netipx/ipx_pcb.h -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_pcb.h
+++ sys/netipx/ipx_pcb.h
@@ -1,8 +1,35 @@
/*-
- * Copyright (c) 2004-2005 Robert N. M. Watson
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California.
+ * Copyright (c) 2004-2006 Robert N. M. Watson
+ * 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
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,7 +61,7 @@
*
* @(#)ipx_pcb.h
*
- * $FreeBSD: src/sys/netipx/ipx_pcb.h,v 1.23 2005/01/09 05:00:41 rwatson Exp $
+ * $FreeBSD: src/sys/netipx/ipx_pcb.h,v 1.29 2007/05/11 10:38:34 rwatson Exp $
*/
#ifndef _NETIPX_IPX_PCB_H_
@@ -68,13 +95,16 @@
extern struct mtx ipxpcb_list_mtx;
#endif
-/* possible flags */
-
-#define IPXP_IN_ABORT 0x1 /* calling abort through socket */
-#define IPXP_RAWIN 0x2 /* show headers on input */
-#define IPXP_RAWOUT 0x4 /* show header on output */
-#define IPXP_ALL_PACKETS 0x8 /* Turn off higher proto processing */
-#define IPXP_CHECKSUM 0x10 /* use checksum on this socket */
+/*
+ * IPX/SPX PCB flags.
+ */
+#define IPXP_IN_ABORT 0x1 /* Calling abort through socket. */
+#define IPXP_RAWIN 0x2 /* Show headers on input. */
+#define IPXP_RAWOUT 0x4 /* Show header on output. */
+#define IPXP_ALL_PACKETS 0x8 /* Turn off higher proto processing. */
+#define IPXP_CHECKSUM 0x10 /* Use checksum on this socket. */
+#define IPXP_DROPPED 0x20 /* Connection dropped. */
+#define IPXP_SPX 0x40 /* SPX PCB. */
#define IPX_WILDCARD 1
@@ -91,17 +121,17 @@
#ifdef _KERNEL
int ipx_pcballoc(struct socket *so, struct ipxpcbhead *head,
- struct thread *p);
+ struct thread *p);
int ipx_pcbbind(struct ipxpcb *ipxp, struct sockaddr *nam,
- struct thread *p);
+ struct thread *p);
int ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam,
- struct thread *p);
+ struct thread *p);
void ipx_pcbdetach(struct ipxpcb *ipxp);
void ipx_pcbdisconnect(struct ipxpcb *ipxp);
-struct ipxpcb *
- ipx_pcblookup(struct ipx_addr *faddr, int lport, int wildp);
-void ipx_setpeeraddr(struct ipxpcb *ipxp, struct sockaddr **nam);
-void ipx_setsockaddr(struct ipxpcb *ipxp, struct sockaddr **nam);
+void ipx_pcbfree(struct ipxpcb *ipxp);
+struct ipxpcb *ipx_pcblookup(struct ipx_addr *faddr, u_short lport, int wildp);
+void ipx_getpeeraddr(struct ipxpcb *ipxp, struct sockaddr **nam);
+void ipx_getsockaddr(struct ipxpcb *ipxp, struct sockaddr **nam);
#define IPX_LIST_LOCK_INIT() mtx_init(&ipxpcb_list_mtx, "ipx_list_mtx", \
NULL, MTX_DEF | MTX_RECURSE)
Index: ipx_if.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_if.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_if.h -L sys/netipx/ipx_if.h -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_if.h
+++ sys/netipx/ipx_if.h
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -33,7 +58,7 @@
*
* @(#)ipx_if.h
*
- * $FreeBSD: src/sys/netipx/ipx_if.h,v 1.15 2005/01/07 01:45:47 imp Exp $
+ * $FreeBSD: src/sys/netipx/ipx_if.h,v 1.18 2007/06/13 14:01:43 rwatson Exp $
*/
#ifndef _NETIPX_IPX_IF_H_
@@ -79,18 +104,10 @@
#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;
-struct ipx_ifaddr *ipx_iaonnetof(struct ipx_addr *dst);
+struct ipx_ifaddr *ipx_iaonnetof(struct ipx_addr *dst);
#endif
#endif /* !_NETIPX_IPX_IF_H_ */
Index: ipx_usrreq.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_usrreq.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_usrreq.c -L sys/netipx/ipx_usrreq.c -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_usrreq.c
+++ sys/netipx/ipx_usrreq.c
@@ -1,8 +1,35 @@
/*-
- * Copyright (c) 2004-2005 Robert N. M. Watson
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California.
+ * Copyright (c) 2004-2006 Robert N. M. Watson
+ * 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
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/ipx_usrreq.c,v 1.52 2005/01/09 05:15:59 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/ipx_usrreq.c,v 1.62 2007/06/13 14:01:43 rwatson Exp $");
#include "opt_ipx.h"
@@ -44,6 +71,7 @@
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
+#include <sys/priv.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
@@ -59,7 +87,6 @@
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
-#include <netipx/ipx_ip.h>
#include <netipx/ipx_pcb.h>
#include <netipx/ipx_var.h>
@@ -74,12 +101,12 @@
SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxrecvspace, CTLFLAG_RW,
&ipxrecvspace, 0, "");
-static int ipx_usr_abort(struct socket *so);
+static void ipx_usr_abort(struct socket *so);
static int ipx_attach(struct socket *so, int proto, struct thread *td);
static int ipx_bind(struct socket *so, struct sockaddr *nam, struct thread *td);
static int ipx_connect(struct socket *so, struct sockaddr *nam,
struct thread *td);
-static int ipx_detach(struct socket *so);
+static void ipx_detach(struct socket *so);
static int ipx_disconnect(struct socket *so);
static int ipx_send(struct socket *so, int flags, struct mbuf *m,
struct sockaddr *addr, struct mbuf *control,
@@ -87,6 +114,7 @@
static int ipx_shutdown(struct socket *so);
static int ripx_attach(struct socket *so, int proto, struct thread *td);
static int ipx_output(struct ipxpcb *ipxp, struct mbuf *m0);
+static void ipx_usr_close(struct socket *so);
struct pr_usrreqs ipx_usrreqs = {
.pru_abort = ipx_usr_abort,
@@ -100,6 +128,7 @@
.pru_send = ipx_send,
.pru_shutdown = ipx_shutdown,
.pru_sockaddr = ipx_sockaddr,
+ .pru_close = ipx_usr_close,
};
struct pr_usrreqs ripx_usrreqs = {
@@ -114,17 +143,16 @@
.pru_send = ipx_send,
.pru_shutdown = ipx_shutdown,
.pru_sockaddr = ipx_sockaddr,
+ .pru_close = ipx_usr_close,
};
/*
* This may also be called for raw listeners.
*/
void
-ipx_input(m, ipxp)
- struct mbuf *m;
- register struct ipxpcb *ipxp;
+ipx_input(struct mbuf *m, struct ipxpcb *ipxp)
{
- register struct ipx *ipx = mtod(m, struct ipx *);
+ struct ipx *ipx = mtod(m, struct ipx *);
struct ifnet *ifp = m->m_pkthdr.rcvif;
struct sockaddr_ipx ipx_ipx;
@@ -140,7 +168,7 @@
ipx_ipx.sipx_zero[0] = '\0';
ipx_ipx.sipx_zero[1] = '\0';
if (ipx_neteqnn(ipx->ipx_sna.x_net, ipx_zeronet) && ifp != NULL) {
- register struct ifaddr *ifa;
+ struct ifaddr *ifa;
for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa != NULL;
ifa = TAILQ_NEXT(ifa, ifa_link)) {
@@ -169,9 +197,7 @@
* the specified error.
*/
void
-ipx_drop(ipxp, errno)
- register struct ipxpcb *ipxp;
- int errno;
+ipx_drop(struct ipxpcb *ipxp, int errno)
{
struct socket *so = ipxp->ipxp_socket;
@@ -195,14 +221,12 @@
}
static int
-ipx_output(ipxp, m0)
- struct ipxpcb *ipxp;
- struct mbuf *m0;
-{
- register struct ipx *ipx;
- register struct socket *so;
- register int len = 0;
- register struct route *ro;
+ipx_output(struct ipxpcb *ipxp, struct mbuf *m0)
+{
+ struct ipx *ipx;
+ struct socket *so;
+ int len = 0;
+ struct route *ro;
struct mbuf *m;
struct mbuf *mprev = NULL;
@@ -297,7 +321,7 @@
}
if ((ro->ro_rt->rt_flags & RTF_GATEWAY) == 0) {
- register struct ipx_addr *dst =
+ struct ipx_addr *dst =
&satoipx_addr(ro->ro_dst);
dst->x_host = ipx->ipx_dna.x_host;
}
@@ -317,9 +341,7 @@
}
int
-ipx_ctloutput(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
+ipx_ctloutput(struct socket *so, struct sockopt *sopt)
{
struct ipxpcb *ipxp = sotoipxpcb(so);
int mask, error, optval;
@@ -327,9 +349,8 @@
struct ipx ioptval;
long seq;
+ KASSERT(ipxp != NULL, ("ipx_ctloutput: ipxp == NULL"));
error = 0;
- if (ipxp == NULL)
- return (EINVAL);
switch (sopt->sopt_dir) {
case SOPT_GET:
@@ -415,11 +436,6 @@
/* 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;
}
@@ -428,51 +444,39 @@
return (error);
}
-static int
-ipx_usr_abort(so)
- struct socket *so;
+static void
+ipx_usr_abort(struct socket *so)
{
- struct ipxpcb *ipxp = sotoipxpcb(so);
- IPX_LIST_LOCK();
- IPX_LOCK(ipxp);
- ipx_pcbdetach(ipxp);
- IPX_LIST_UNLOCK();
+ /* XXXRW: Possibly ipx_disconnect() here? */
soisdisconnected(so);
- ACCEPT_LOCK();
- SOCK_LOCK(so);
- sotryfree(so);
- return (0);
}
static int
-ipx_attach(so, proto, td)
- struct socket *so;
- int proto;
- struct thread *td;
+ipx_attach(struct socket *so, int proto, struct thread *td)
{
+#ifdef INVARIANTS
struct ipxpcb *ipxp = sotoipxpcb(so);
+#endif
int error;
- if (ipxp != NULL)
- return (EINVAL);
+ KASSERT(ipxp == NULL, ("ipx_attach: ipxp != NULL"));
+ error = soreserve(so, ipxsendspace, ipxrecvspace);
+ if (error != 0)
+ return (error);
IPX_LIST_LOCK();
error = ipx_pcballoc(so, &ipxpcb_list, td);
IPX_LIST_UNLOCK();
- if (error == 0)
- error = soreserve(so, ipxsendspace, ipxrecvspace);
return (error);
}
static int
-ipx_bind(so, nam, td)
- struct socket *so;
- struct sockaddr *nam;
- struct thread *td;
+ipx_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct ipxpcb *ipxp = sotoipxpcb(so);
int error;
+ KASSERT(ipxp != NULL, ("ipx_bind: ipxp == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
error = ipx_pcbbind(ipxp, nam, td);
@@ -481,15 +485,21 @@
return (error);
}
+static void
+ipx_usr_close(struct socket *so)
+{
+
+ /* XXXRW: Possibly ipx_disconnect() here? */
+ soisdisconnected(so);
+}
+
static int
-ipx_connect(so, nam, td)
- struct socket *so;
- struct sockaddr *nam;
- struct thread *td;
+ipx_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct ipxpcb *ipxp = sotoipxpcb(so);
int error;
+ KASSERT(ipxp != NULL, ("ipx_connect: ipxp == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
if (!ipx_nullhost(ipxp->ipxp_faddr)) {
@@ -505,28 +515,27 @@
return (error);
}
-static int
-ipx_detach(so)
- struct socket *so;
+static void
+ipx_detach(struct socket *so)
{
struct ipxpcb *ipxp = sotoipxpcb(so);
- if (ipxp == NULL)
- return (ENOTCONN);
+ /* XXXRW: Should assert detached. */
+ KASSERT(ipxp != NULL, ("ipx_detach: ipxp == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
ipx_pcbdetach(ipxp);
+ ipx_pcbfree(ipxp);
IPX_LIST_UNLOCK();
- return (0);
}
static int
-ipx_disconnect(so)
- struct socket *so;
+ipx_disconnect(struct socket *so)
{
struct ipxpcb *ipxp = sotoipxpcb(so);
int error;
+ KASSERT(ipxp != NULL, ("ipx_disconnect: ipxp == NULL"));
IPX_LIST_LOCK();
IPX_LOCK(ipxp);
error = 0;
@@ -543,29 +552,24 @@
}
int
-ipx_peeraddr(so, nam)
- struct socket *so;
- struct sockaddr **nam;
+ipx_peeraddr(struct socket *so, struct sockaddr **nam)
{
struct ipxpcb *ipxp = sotoipxpcb(so);
- ipx_setpeeraddr(ipxp, nam);
+ KASSERT(ipxp != NULL, ("ipx_peeraddr: ipxp == NULL"));
+ ipx_getpeeraddr(ipxp, nam);
return (0);
}
static int
-ipx_send(so, flags, m, nam, control, td)
- struct socket *so;
- int flags;
- struct mbuf *m;
- struct sockaddr *nam;
- struct mbuf *control;
- struct thread *td;
+ipx_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
+ struct mbuf *control, struct thread *td)
{
int error;
struct ipxpcb *ipxp = sotoipxpcb(so);
struct ipx_addr laddr;
+ KASSERT(ipxp != NULL, ("ipxp_send: ipxp == NULL"));
/*
* Attempt to only acquire the necessary locks: if the socket is
* already connected, we don't need to hold the IPX list lock to be
@@ -619,32 +623,36 @@
ipx_shutdown(so)
struct socket *so;
{
+
+ KASSERT(so->so_pcb != NULL, ("ipx_shutdown: so_pcb == NULL"));
socantsendmore(so);
return (0);
}
int
-ipx_sockaddr(so, nam)
- struct socket *so;
- struct sockaddr **nam;
+ipx_sockaddr(struct socket *so, struct sockaddr **nam)
{
struct ipxpcb *ipxp = sotoipxpcb(so);
- ipx_setsockaddr(ipxp, nam);
+ KASSERT(ipxp != NULL, ("ipx_sockaddr: ipxp == NULL"));
+ ipx_getsockaddr(ipxp, nam);
return (0);
}
static int
-ripx_attach(so, proto, td)
- struct socket *so;
- int proto;
- struct thread *td;
+ripx_attach(struct socket *so, int proto, struct thread *td)
{
int error = 0;
struct ipxpcb *ipxp = sotoipxpcb(so);
- if (td != NULL && (error = suser(td)) != 0)
- return (error);
+ KASSERT(ipxp == NULL, ("ripx_attach: ipxp != NULL"));
+
+ if (td != NULL) {
+ error = priv_check(td, PRIV_NETIPX_RAW);
+ if (error)
+ return (error);
+ }
+
/*
* We hold the IPX list lock for the duration as address parameters
* of the IPX pcb are changed. Since no one else holds a reference
--- sys/netipx/ipx_ip.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*-
- * Copyright (c) 1995, Mike Mitchell
- * 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.
- * 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: src/sys/netipx/ipx_ip.h,v 1.17 2005/06/10 16:49:22 brooks Exp $
- */
-
-#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_ */
Index: ipx_proto.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_proto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_proto.c -L sys/netipx/ipx_proto.c -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_proto.c
+++ sys/netipx/ipx_proto.c
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -35,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/ipx_proto.c,v 1.19.2.1 2005/11/16 10:31:23 ru Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/ipx_proto.c,v 1.22 2007/01/08 22:14:00 rwatson Exp $");
#include "opt_ipx.h"
@@ -53,13 +78,14 @@
#include <netipx/ipx_var.h>
#include <netipx/spx.h>
-extern struct domain ipxdomain;
static struct pr_usrreqs nousrreqs;
/*
* IPX protocol family: IPX, ERR, PXP, SPX, ROUTE.
*/
+static struct domain ipxdomain;
+
static struct protosw ipxsw[] = {
{
.pr_domain = &ipxdomain,
Index: spx_var.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/spx_var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/spx_var.h -L sys/netipx/spx_var.h -u -r1.1.1.1 -r1.2
--- sys/netipx/spx_var.h
+++ sys/netipx/spx_var.h
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -33,7 +58,7 @@
*
* @(#)spx_var.h
*
- * $FreeBSD: src/sys/netipx/spx_var.h,v 1.10 2005/01/07 01:45:47 imp Exp $
+ * $FreeBSD: src/sys/netipx/spx_var.h,v 1.11 2007/01/08 22:14:00 rwatson Exp $
*/
#ifndef _NETIPX_SPX_VAR_H_
Index: ipx_cksum.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_cksum.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_cksum.c -L sys/netipx/ipx_cksum.c -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_cksum.c
+++ sys/netipx/ipx_cksum.c
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1982, 1992, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -35,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/ipx_cksum.c,v 1.13 2005/01/07 01:45:47 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/ipx_cksum.c,v 1.15 2007/05/11 10:38:34 rwatson Exp $");
#include <sys/param.h>
#include <sys/mbuf.h>
@@ -48,7 +73,8 @@
#define SUMADV sum += *w++
u_short
-ipx_cksum(struct mbuf *m, int len) {
+ipx_cksum(struct mbuf *m, int len)
+{
u_int32_t sum = 0;
u_char *w;
u_char oldtc;
Index: spx_timer.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/spx_timer.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/spx_timer.h -L sys/netipx/spx_timer.h -u -r1.1.1.1 -r1.2
--- sys/netipx/spx_timer.h
+++ sys/netipx/spx_timer.h
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1982, 1986, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -33,7 +58,7 @@
*
* @(#)spx_timer.h
*
- * $FreeBSD: src/sys/netipx/spx_timer.h,v 1.11 2005/01/07 01:45:47 imp Exp $
+ * $FreeBSD: src/sys/netipx/spx_timer.h,v 1.12 2007/01/08 22:14:00 rwatson Exp $
*/
#ifndef _NETIPX_SPX_TIMER_H_
Index: spx_debug.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/spx_debug.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/spx_debug.c -L sys/netipx/spx_debug.c -u -r1.1.1.1 -r1.2
--- sys/netipx/spx_debug.c
+++ sys/netipx/spx_debug.c
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -35,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/spx_debug.c,v 1.16 2005/01/07 01:45:47 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/spx_debug.c,v 1.19 2007/07/30 11:06:42 des Exp $");
#include "opt_inet.h"
#include "opt_tcpdebug.h"
@@ -44,6 +69,8 @@
#include <sys/systm.h>
#include <sys/protosw.h>
+#define TCPSTATES /* for logging */
+
#include <netinet/in_systm.h>
#include <netinet/tcp_fsm.h>
@@ -65,12 +92,8 @@
* spx debug routines
*/
void
-spx_trace(act, ostate, sp, si, req)
- short act;
- u_char ostate;
- struct spxpcb *sp;
- struct spx *si;
- int req;
+spx_trace(short act, u_char ostate, struct spxpcb *sp, struct spx *si,
+ int req)
{
#ifdef INET
#ifdef TCPDEBUG
Index: ipx.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx.h -L sys/netipx/ipx.h -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx.h
+++ sys/netipx/ipx.h
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -33,7 +58,7 @@
*
* @(#)ipx.h
*
- * $FreeBSD: src/sys/netipx/ipx.h,v 1.21 2005/05/27 12:25:42 rwatson Exp $
+ * $FreeBSD: src/sys/netipx/ipx.h,v 1.24 2007/06/13 14:01:43 rwatson Exp $
*/
#ifndef _NETIPX_IPX_H_
@@ -90,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
@@ -162,8 +187,8 @@
#include <sys/cdefs.h>
__BEGIN_DECLS
-struct ipx_addr ipx_addr(const char *);
-char *ipx_ntoa(struct ipx_addr);
+struct ipx_addr ipx_addr(const char *);
+char *ipx_ntoa(struct ipx_addr);
__END_DECLS
#endif /* !_NETIPX_IPX_H_ */
Index: spx.h
===================================================================
RCS file: /home/cvs/src/sys/netipx/spx.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/spx.h -L sys/netipx/spx.h -u -r1.1.1.1 -r1.2
--- sys/netipx/spx.h
+++ sys/netipx/spx.h
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -33,7 +58,7 @@
*
* @(#)spx.h
*
- * $FreeBSD: src/sys/netipx/spx.h,v 1.19 2005/01/07 01:45:47 imp Exp $
+ * $FreeBSD: src/sys/netipx/spx.h,v 1.20 2007/01/08 22:14:00 rwatson Exp $
*/
#ifndef _NETIPX_SPX_H_
Index: ipx_pcb.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx_pcb.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx_pcb.c -L sys/netipx/ipx_pcb.c -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx_pcb.c
+++ sys/netipx/ipx_pcb.c
@@ -1,8 +1,35 @@
/*-
- * Copyright (c) 2004-2005 Robert N. M. Watson
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California.
+ * Copyright (c) 2004-2006 Robert N. M. Watson
+ * 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
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,11 +63,12 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/ipx_pcb.c,v 1.43 2005/01/09 05:10:43 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/ipx_pcb.c,v 1.49 2007/05/11 10:38:34 rwatson Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -56,13 +84,11 @@
static u_short ipxpcb_lport_cache;
int
-ipx_pcballoc(so, head, td)
- struct socket *so;
- struct ipxpcbhead *head;
- struct thread *td;
+ipx_pcballoc(struct socket *so, struct ipxpcbhead *head, struct thread *td)
{
- register struct ipxpcb *ipxp;
+ struct ipxpcb *ipxp;
+ KASSERT(so->so_pcb == NULL, ("ipx_pcballoc: so_pcb != NULL"));
IPX_LIST_LOCK_ASSERT();
MALLOC(ipxp, struct ipxpcb *, sizeof *ipxp, M_PCB, M_NOWAIT | M_ZERO);
@@ -78,12 +104,9 @@
}
int
-ipx_pcbbind(ipxp, nam, td)
- register struct ipxpcb *ipxp;
- struct sockaddr *nam;
- struct thread *td;
+ipx_pcbbind(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td)
{
- register struct sockaddr_ipx *sipx;
+ struct sockaddr_ipx *sipx;
u_short lport = 0;
IPX_LIST_LOCK_ASSERT();
@@ -105,11 +128,10 @@
lport = sipx->sipx_port;
if (lport) {
u_short aport = ntohs(lport);
- int error;
- if (aport < IPXPORT_RESERVED &&
- td != NULL && (error = suser(td)) != 0)
- return (error);
+ if (aport < IPXPORT_RESERVED && td != NULL &&
+ priv_check(td, PRIV_NETIPX_RESERVEDPORT))
+ return (EACCES);
if (ipx_pcblookup(&zeroipx_addr, lport, 0))
return (EADDRINUSE);
}
@@ -134,15 +156,12 @@
* then pick one.
*/
int
-ipx_pcbconnect(ipxp, nam, td)
- struct ipxpcb *ipxp;
- struct sockaddr *nam;
- struct thread *td;
+ipx_pcbconnect(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *td)
{
struct ipx_ifaddr *ia;
- register struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)nam;
- register struct ipx_addr *dst;
- register struct route *ro;
+ struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)nam;
+ struct ipx_addr *dst;
+ struct route *ro;
struct ifnet *ifp;
IPX_LIST_LOCK_ASSERT();
@@ -264,31 +283,36 @@
}
void
-ipx_pcbdisconnect(ipxp)
- struct ipxpcb *ipxp;
+ipx_pcbdisconnect(struct ipxpcb *ipxp)
{
IPX_LIST_LOCK_ASSERT();
IPX_LOCK_ASSERT(ipxp);
ipxp->ipxp_faddr = zeroipx_addr;
- if (ipxp->ipxp_socket->so_state & SS_NOFDREF)
- ipx_pcbdetach(ipxp);
}
void
-ipx_pcbdetach(ipxp)
- struct ipxpcb *ipxp;
+ipx_pcbdetach(struct ipxpcb *ipxp)
{
struct socket *so = ipxp->ipxp_socket;
IPX_LIST_LOCK_ASSERT();
IPX_LOCK_ASSERT(ipxp);
- ACCEPT_LOCK();
- SOCK_LOCK(so);
so->so_pcb = NULL;
- sotryfree(so);
+ ipxp->ipxp_socket = NULL;
+}
+
+void
+ipx_pcbfree(struct ipxpcb *ipxp)
+{
+
+ KASSERT(ipxp->ipxp_socket == NULL,
+ ("ipx_pcbfree: ipxp_socket != NULL"));
+ IPX_LIST_LOCK_ASSERT();
+ IPX_LOCK_ASSERT(ipxp);
+
if (ipxp->ipxp_route.ro_rt != NULL)
RTFREE(ipxp->ipxp_route.ro_rt);
LIST_REMOVE(ipxp, ipxp_list);
@@ -297,9 +321,7 @@
}
void
-ipx_setsockaddr(ipxp, nam)
- register struct ipxpcb *ipxp;
- struct sockaddr **nam;
+ipx_getsockaddr(struct ipxpcb *ipxp, struct sockaddr **nam)
{
struct sockaddr_ipx *sipx, ssipx;
@@ -314,9 +336,7 @@
}
void
-ipx_setpeeraddr(ipxp, nam)
- register struct ipxpcb *ipxp;
- struct sockaddr **nam;
+ipx_getpeeraddr(struct ipxpcb *ipxp, struct sockaddr **nam)
{
struct sockaddr_ipx *sipx, ssipx;
@@ -331,12 +351,9 @@
}
struct ipxpcb *
-ipx_pcblookup(faddr, lport, wildp)
- struct ipx_addr *faddr;
- u_short lport;
- int wildp;
+ipx_pcblookup(struct ipx_addr *faddr, u_short lport, int wildp)
{
- register struct ipxpcb *ipxp, *match = NULL;
+ struct ipxpcb *ipxp, *match = NULL;
int matchwild = 3, wildcard;
u_short fport;
Index: ipx.c
===================================================================
RCS file: /home/cvs/src/sys/netipx/ipx.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/ipx.c -L sys/netipx/ipx.c -u -r1.1.1.1 -r1.2
--- sys/netipx/ipx.c
+++ sys/netipx/ipx.c
@@ -1,5 +1,4 @@
/*-
- * Copyright (c) 1995, Mike Mitchell
* Copyright (c) 1984, 1985, 1986, 1987, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -11,6 +10,32 @@
* 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
@@ -35,12 +60,13 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netipx/ipx.c,v 1.30 2005/01/09 05:34:37 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netipx/ipx.c,v 1.33 2007/06/13 22:42:43 rwatson Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <sys/sockio.h>
#include <sys/socket.h>
@@ -64,16 +90,12 @@
* Generic internet control operations (ioctl's).
*/
int
-ipx_control(so, cmd, data, ifp, td)
- struct socket *so;
- u_long cmd;
- caddr_t data;
- register struct ifnet *ifp;
- struct thread *td;
+ipx_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
+ struct thread *td)
{
- register struct ifreq *ifr = (struct ifreq *)data;
- register struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data;
- register struct ipx_ifaddr *ia;
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data;
+ struct ipx_ifaddr *ia;
struct ifaddr *ifa;
struct ipx_ifaddr *oia;
int dstIsNew, hostIsNew;
@@ -237,10 +259,9 @@
* Delete any previous route for an old address.
*/
static void
-ipx_ifscrub(ifp, ia)
- register struct ifnet *ifp;
- register struct ipx_ifaddr *ia;
+ipx_ifscrub(struct ifnet *ifp, struct ipx_ifaddr *ia)
{
+
if (ia->ia_flags & IFA_ROUTE) {
if (ifp->if_flags & IFF_POINTOPOINT) {
rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
@@ -254,11 +275,8 @@
* and routing table entry.
*/
static int
-ipx_ifinit(ifp, ia, sipx, scrub)
- register struct ifnet *ifp;
- register struct ipx_ifaddr *ia;
- register struct sockaddr_ipx *sipx;
- int scrub;
+ipx_ifinit(struct ifnet *ifp, struct ipx_ifaddr *ia,
+ struct sockaddr_ipx *sipx, int scrub)
{
struct sockaddr_ipx oldaddr;
int s = splimp(), error;
@@ -310,12 +328,11 @@
* Return address info for specified internet network.
*/
struct ipx_ifaddr *
-ipx_iaonnetof(dst)
- register struct ipx_addr *dst;
+ipx_iaonnetof(struct ipx_addr *dst)
{
- register struct ipx_ifaddr *ia;
- register struct ipx_addr *compare;
- register struct ifnet *ifp;
+ struct ipx_ifaddr *ia;
+ struct ipx_addr *compare;
+ struct ifnet *ifp;
struct ipx_ifaddr *ia_maybe = NULL;
union ipx_net net = dst->x_net;
@@ -338,13 +355,12 @@
void
-ipx_printhost(addr)
-register struct ipx_addr *addr;
+ipx_printhost(struct ipx_addr *addr)
{
u_short port;
struct ipx_addr work = *addr;
- register char *p; register u_char *q;
- register char *net = "", *host = "";
+ char *p; u_char *q;
+ char *net = "", *host = "";
char cport[10], chost[15], cnet[15];
port = ntohs(work.x_port);
--- sys/netipx/ipx_ip.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/*-
- * Copyright (c) 1995, Mike Mitchell
- * 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.
- * 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: src/sys/netipx/ipx_ip.c,v 1.40.2.1 2006/03/29 12:42:43 rwatson Exp $");
-
-/*
- * Software interface driver for encapsulating IPX in IP.
- */
-
-#include "opt_inet.h"
-#include "opt_ipx.h"
-
-#ifdef IPXIP
-#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 <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 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()
-{
- register struct ifnet_en *m;
- register 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(ifp, cmd, data)
- register 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);
-
-
- default:
- error = EINVAL;
- }
- return (error);
-}
-
-static struct mbuf *ipxip_badlen;
-static struct mbuf *ipxip_lastin;
-static int ipxip_hold_input;
-
-void
-ipxip_input(m, hlen)
- register struct mbuf *m;
- int hlen;
-{
- register struct ip *ip;
- register 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(ifp, m, dst, rt)
- struct ifnet *ifp;
- struct mbuf *m;
- struct sockaddr *dst;
- struct rtentry *rt;
-{
- register struct ifnet_en *ifn = (struct ifnet_en *)ifp->if_softc;
- register struct ip *ip;
- register struct route *ro = &(ifn->ifen_route);
- register int len = 0;
- register struct ipx *ipx = mtod(m, struct ipx *);
- 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_HEADER, 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);
- m_freem(m);
- return (ENETUNREACH);
-}
-
-static void
-ipxipstart(ifp)
-struct ifnet *ifp;
-{
- panic("ipxip_start called\n");
-}
-
-static struct ifreq ifr_ipxip = {"ipxip0"};
-
-int
-ipxip_route(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
-{
- int error;
- struct ifnet_en *ifn;
- struct sockaddr_in *src;
- struct ipxip_req rq;
- struct sockaddr_ipx *ipx_dst;
- struct sockaddr_in *ip_dst;
- struct route ro;
-
- 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?
- */
- {
- register struct in_ifaddr *ia;
- struct ifnet *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(ifp)
-struct ifnet *ifp;
-{
- register 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(cmd, sa, dummy)
- 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(dst)
- register struct in_addr *dst;
-{
- register 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;
- }
- }
-}
-#endif /* IPXIP */
Index: README
===================================================================
RCS file: /home/cvs/src/sys/netipx/README,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netipx/README -L sys/netipx/README -u -r1.1.1.1 -r1.2
--- sys/netipx/README
+++ sys/netipx/README
@@ -1,4 +1,4 @@
-$FreeBSD: src/sys/netipx/README,v 1.6 2005/04/10 18:05:46 rwatson Exp $
+$FreeBSD: src/sys/netipx/README,v 1.8 2006/03/27 09:10:09 rwatson Exp $
This protocol implements IPX/SPX over Ethernet_II frame type 0x8137.
Please note: the SPX implementation may require further work and testing
@@ -14,14 +14,36 @@
Some Address
jhay at mikom.csir.co.za
+Adapted for multi-processor, multi-threaded network stack by Robert N. M.
+Watson, Computer Laboratory, University of Cambridge.
+
--- Copyright Information ---
/*-
Copyright (c) 1984, 1985, 1986, 1987, 1993
The Regents of the University of California. All rights reserved.
-Modifications Copyright (c) 2004-2005 Robert N. M. Watson
Modifications Copyright (c) 1995, Mike Mitchell
Modifications Copyright (c) 1995, John Hay
+Modifications Copyright (c) 2004-2006 Robert N. M. Watson
*/
+
+--- TODO ---
+
+(1) netipx default socket buffer sizes are very small by contemporary
+ standards, and should be increased following testing and measurement.
+
+(2) SPX will free the PCB and socket buffer memory on close(), which means
+ close() in effects terminates the transfer of any outstanding buffered
+ but unsent data. As with TCP, it should instead grab its own
+ reference to the socket so that it is not released, as hold onto it
+ until the data transfer is complete.
+
+(3) Raw socket capture of IPX output intercepts packets in the SPX output
+ routine in order to feed them back into the raw socket. This results
+ in recursion into the socket code in the transmit path; instead,
+ captured packets should be fed into a netisr that reinjects them into
+ raw sockets from a new (asynchronous) context.
+
+(4) IPX over IP encapsulation needs work to make it properly MPSAFE.
More information about the Midnightbsd-cvs
mailing list