summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1997-04-27 20:01:29 +0000
committerwollman <wollman@FreeBSD.org>1997-04-27 20:01:29 +0000
commit6afbf203bd570424ecf3f9d9d9ced17f82c81adc (patch)
tree41103dcf8addc8e73880fc79975713ce1e6ba14c /sys/net/rtsock.c
parentced78602fea5284de7f4cb1673405ad3f3ad57ce (diff)
downloadFreeBSD-src-6afbf203bd570424ecf3f9d9d9ced17f82c81adc.zip
FreeBSD-src-6afbf203bd570424ecf3f9d9d9ced17f82c81adc.tar.gz
The long-awaited mega-massive-network-code- cleanup. Part I.
This commit includes the following changes: 1) Old-style (pr_usrreq()) protocols are no longer supported, the compatibility glue for them is deleted, and the kernel will panic on boot if any are compiled in. 2) Certain protocol entry points are modified to take a process structure, so they they can easily tell whether or not it is possible to sleep, and also to access credentials. 3) SS_PRIV is no more, and with it goes the SO_PRIVSTATE setsockopt() call. Protocols should use the process pointer they are now passed. 4) The PF_LOCAL and PF_ROUTE families have been updated to use the new style, as has the `raw' skeleton family. 5) PF_LOCAL sockets now obey the process's umask when creating a socket in the filesystem. As a result, LINT is now broken. I'm hoping that some enterprising hacker with a bit more time will either make the broken bits work (should be easy for netipx) or dike them out.
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c227
1 files changed, 178 insertions, 49 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 36afca9..ae1a900 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -31,9 +31,10 @@
* SUCH DAMAGE.
*
* @(#)rtsock.c 8.5 (Berkeley) 11/2/94
- * $Id$
+ * $Id: rtsock.c,v 1.26 1997/02/22 09:41:15 peter Exp $
*/
+
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/systm.h>
@@ -69,8 +70,6 @@ static void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
static int sysctl_dumpentry __P((struct radix_node *rn, void *vw));
static int sysctl_iflist __P((int af, struct walkarg *w));
static int route_output __P((struct mbuf *, struct socket *));
-static int route_usrreq __P((struct socket *,
- int, struct mbuf *, struct mbuf *, struct mbuf *));
static void rt_setmetrics __P((u_long, struct rt_metrics *, struct rt_metrics *));
/* Sleazy use of local variables throughout file, warning!!!! */
@@ -82,62 +81,191 @@ static void rt_setmetrics __P((u_long, struct rt_metrics *, struct rt_metrics *
#define ifaaddr info.rti_info[RTAX_IFA]
#define brdaddr info.rti_info[RTAX_BRD]
-/*ARGSUSED*/
+/*
+ * It really doesn't make any sense at all for this code to share much
+ * with raw_usrreq.c, since its functionality is so restricted. XXX
+ */
+static int
+rts_abort(struct socket *so)
+{
+ int s, error;
+ s = splnet();
+ error = raw_usrreqs.pru_abort(so);
+ splx(s);
+ return error;
+}
+
+/* pru_accept is EOPNOTSUPP */
+
static int
-route_usrreq(so, req, m, nam, control)
- register struct socket *so;
- int req;
- struct mbuf *m, *nam, *control;
+rts_attach(struct socket *so, int proto, struct proc *p)
{
- register int error = 0;
- register struct rawcb *rp = sotorawcb(so);
- int s;
-
- if (req == PRU_ATTACH) {
- MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
- so->so_pcb = (caddr_t)rp;
- if (so->so_pcb)
- bzero(so->so_pcb, sizeof(*rp));
+ struct rawcb *rp;
+ int s, error;
+
+ if (sotorawcb(so) != 0)
+ return EISCONN; /* XXX panic? */
+ MALLOC(rp, struct rawcb *, sizeof *rp, M_PCB, M_WAITOK); /* XXX */
+ if (rp == 0)
+ return ENOBUFS;
+ bzero(rp, sizeof *rp);
+
+ /*
+ * The splnet() is necessary to block protocols from sending
+ * error notifications (like RTM_REDIRECT or RTM_LOSING) while
+ * this PCB is extant but incompletely initialized.
+ * Probably we should try to do more of this work beforehand and
+ * eliminate the spl.
+ */
+ s = splnet();
+ so->so_pcb = (caddr_t)rp;
+ error = raw_usrreqs.pru_attach(so, proto, p);
+ rp = sotorawcb(so);
+ if (error) {
+ splx(s);
+ free(rp, M_PCB);
+ return error;
+ }
+ switch(rp->rcb_proto.sp_protocol) {
+ case AF_INET:
+ route_cb.ip_count++;
+ break;
+ case AF_IPX:
+ route_cb.ipx_count++;
+ break;
+ case AF_NS:
+ route_cb.ns_count++;
+ break;
+ case AF_ISO:
+ route_cb.iso_count++;
+ break;
}
- if (req == PRU_DETACH && rp) {
- int af = rp->rcb_proto.sp_protocol;
- if (af == AF_INET)
+ rp->rcb_faddr = &route_src;
+ route_cb.any_count++;
+ soisconnected(so);
+ so->so_options |= SO_USELOOPBACK;
+ splx(s);
+ return 0;
+}
+
+static int
+rts_bind(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+ int s, error;
+ s = splnet();
+ error = raw_usrreqs.pru_bind(so, nam, p); /* xxx just EINVAL */
+ splx(s);
+ return error;
+}
+
+static int
+rts_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+ int s, error;
+ s = splnet();
+ error = raw_usrreqs.pru_connect(so, nam, p); /* XXX just EINVAL */
+ splx(s);
+ return error;
+}
+
+/* pru_connect2 is EOPNOTSUPP */
+/* pru_control is EOPNOTSUPP */
+
+static int
+rts_detach(struct socket *so)
+{
+ struct rawcb *rp = sotorawcb(so);
+ int s, error;
+
+ s = splnet();
+ if (rp != 0) {
+ switch(rp->rcb_proto.sp_protocol) {
+ case AF_INET:
route_cb.ip_count--;
- else if (af == AF_IPX)
+ break;
+ case AF_IPX:
route_cb.ipx_count--;
- else if (af == AF_NS)
+ break;
+ case AF_NS:
route_cb.ns_count--;
- else if (af == AF_ISO)
+ break;
+ case AF_ISO:
route_cb.iso_count--;
+ break;
+ }
route_cb.any_count--;
}
+ error = raw_usrreqs.pru_detach(so);
+ splx(s);
+ return error;
+}
+
+static int
+rts_disconnect(struct socket *so)
+{
+ int s, error;
s = splnet();
- error = raw_usrreq(so, req, m, nam, control);
- rp = sotorawcb(so);
- if (req == PRU_ATTACH && rp) {
- int af = rp->rcb_proto.sp_protocol;
- if (error) {
- free((caddr_t)rp, M_PCB);
- splx(s);
- return (error);
- }
- if (af == AF_INET)
- route_cb.ip_count++;
- else if (af == AF_IPX)
- route_cb.ipx_count++;
- else if (af == AF_NS)
- route_cb.ns_count++;
- else if (af == AF_ISO)
- route_cb.iso_count++;
- rp->rcb_faddr = &route_src;
- route_cb.any_count++;
- soisconnected(so);
- so->so_options |= SO_USELOOPBACK;
- }
+ error = raw_usrreqs.pru_disconnect(so);
splx(s);
- return (error);
+ return error;
}
+/* pru_listen is EOPNOTSUPP */
+
+static int
+rts_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ int s, error;
+ s = splnet();
+ error = raw_usrreqs.pru_peeraddr(so, nam);
+ splx(s);
+ return error;
+}
+
+/* pru_rcvd is EOPNOTSUPP */
+/* pru_rcvoob is EOPNOTSUPP */
+
+static int
+rts_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct proc *p)
+{
+ int s, error;
+ s = splnet();
+ error = raw_usrreqs.pru_send(so, flags, m, nam, control, p);
+ splx(s);
+ return error;
+}
+
+/* pru_sense is null */
+
+static int
+rts_shutdown(struct socket *so)
+{
+ int s, error;
+ s = splnet();
+ error = raw_usrreqs.pru_shutdown(so);
+ splx(s);
+ return error;
+}
+
+static int
+rts_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ int s, error;
+ s = splnet();
+ error = raw_usrreqs.pru_sockaddr(so, nam);
+ splx(s);
+ return error;
+}
+
+static struct pr_usrreqs route_usrreqs = {
+ rts_abort, pru_accept_notsupp, rts_attach, rts_bind, rts_connect,
+ pru_connect2_notsupp, pru_control_notsupp, rts_detach, rts_disconnect,
+ pru_listen_notsupp, rts_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp,
+ rts_send, pru_sense_null, rts_shutdown, rts_sockaddr,
+ sosend, soreceive, soselect
+};
+
/*ARGSUSED*/
static int
route_output(m, so)
@@ -811,7 +939,7 @@ sysctl_rtsock SYSCTL_HANDLER_ARGS
return (error);
}
-SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock,"");
+SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock, "");
/*
* Definitions of protocols supported in the ROUTE domain.
@@ -822,8 +950,9 @@ extern struct domain routedomain; /* or at least forward */
static struct protosw routesw[] = {
{ SOCK_RAW, &routedomain, 0, PR_ATOMIC|PR_ADDR,
0, route_output, raw_ctlinput, 0,
- route_usrreq,
- raw_init
+ 0,
+ raw_init, 0, 0, 0,
+ &route_usrreqs
}
};
OpenPOWER on IntegriCloud