Module Name: src Committed By: rtr Date: Tue Aug 5 07:55:32 UTC 2014
Modified Files: src/sys/dev: kttcp.c src/sys/dev/bluetooth: bthidev.c btmagic.c btsco.c src/sys/kern: uipc_socket.c uipc_usrreq.c src/sys/net: if_gre.c link_proto.c raw_cb.h raw_usrreq.c rtsock.c src/sys/netatalk: ddp_usrreq.c src/sys/netbt: hci_socket.c l2cap.h l2cap_lower.c l2cap_socket.c l2cap_upper.c rfcomm.h rfcomm_session.c rfcomm_socket.c rfcomm_upper.c sco.h sco_socket.c sco_upper.c src/sys/netinet: raw_ip.c tcp_usrreq.c udp_usrreq.c src/sys/netinet6: raw_ip6.c udp6_usrreq.c src/sys/netipsec: keysock.c src/sys/netmpls: mpls_proto.c src/sys/netnatm: natm.c src/sys/nfs: nfs_socket.c src/sys/rump/net/lib/libsockin: sockin.c src/sys/sys: protosw.h Log Message: split PRU_SEND function out of pr_generic() usrreq switches and put into separate functions xxx_send(struct socket *, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *) - always KASSERT(solocked(so)) even if not implemented - replace calls to pr_generic() with req = PRU_SEND with calls to pr_send() rename existing functions that operate on PCB for consistency (and to free up their names for xxx_send() PRUs - l2cap_send() -> l2cap_send_pcb() - sco_send() -> sco_send_pcb() - rfcomm_send() -> rfcomm_send_pcb() patch reviewed by rmind To generate a diff of this commit: cvs rdiff -u -r1.35 -r1.36 src/sys/dev/kttcp.c cvs rdiff -u -r1.28 -r1.29 src/sys/dev/bluetooth/bthidev.c cvs rdiff -u -r1.10 -r1.11 src/sys/dev/bluetooth/btmagic.c cvs rdiff -u -r1.32 -r1.33 src/sys/dev/bluetooth/btsco.c cvs rdiff -u -r1.231 -r1.232 src/sys/kern/uipc_socket.c cvs rdiff -u -r1.165 -r1.166 src/sys/kern/uipc_usrreq.c cvs rdiff -u -r1.157 -r1.158 src/sys/net/if_gre.c cvs rdiff -u -r1.21 -r1.22 src/sys/net/link_proto.c cvs rdiff -u -r1.22 -r1.23 src/sys/net/raw_cb.h cvs rdiff -u -r1.49 -r1.50 src/sys/net/raw_usrreq.c cvs rdiff -u -r1.160 -r1.161 src/sys/net/rtsock.c cvs rdiff -u -r1.58 -r1.59 src/sys/netatalk/ddp_usrreq.c cvs rdiff -u -r1.37 -r1.38 src/sys/netbt/hci_socket.c cvs rdiff -u -r1.17 -r1.18 src/sys/netbt/l2cap.h src/sys/netbt/l2cap_upper.c cvs rdiff -u -r1.9 -r1.10 src/sys/netbt/l2cap_lower.c cvs rdiff -u -r1.28 -r1.29 src/sys/netbt/l2cap_socket.c cvs rdiff -u -r1.16 -r1.17 src/sys/netbt/rfcomm.h cvs rdiff -u -r1.22 -r1.23 src/sys/netbt/rfcomm_session.c cvs rdiff -u -r1.30 -r1.31 src/sys/netbt/rfcomm_socket.c \ src/sys/netbt/sco_socket.c cvs rdiff -u -r1.19 -r1.20 src/sys/netbt/rfcomm_upper.c cvs rdiff -u -r1.10 -r1.11 src/sys/netbt/sco.h cvs rdiff -u -r1.15 -r1.16 src/sys/netbt/sco_upper.c cvs rdiff -u -r1.142 -r1.143 src/sys/netinet/raw_ip.c cvs rdiff -u -r1.197 -r1.198 src/sys/netinet/tcp_usrreq.c cvs rdiff -u -r1.214 -r1.215 src/sys/netinet/udp_usrreq.c cvs rdiff -u -r1.133 -r1.134 src/sys/netinet6/raw_ip6.c cvs rdiff -u -r1.112 -r1.113 src/sys/netinet6/udp6_usrreq.c cvs rdiff -u -r1.40 -r1.41 src/sys/netipsec/keysock.c cvs rdiff -u -r1.21 -r1.22 src/sys/netmpls/mpls_proto.c cvs rdiff -u -r1.42 -r1.43 src/sys/netnatm/natm.c cvs rdiff -u -r1.191 -r1.192 src/sys/nfs/nfs_socket.c cvs rdiff -u -r1.55 -r1.56 src/sys/rump/net/lib/libsockin/sockin.c cvs rdiff -u -r1.57 -r1.58 src/sys/sys/protosw.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/kttcp.c diff -u src/sys/dev/kttcp.c:1.35 src/sys/dev/kttcp.c:1.36 --- src/sys/dev/kttcp.c:1.35 Fri Jul 25 08:10:35 2014 +++ src/sys/dev/kttcp.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: kttcp.c,v 1.35 2014/07/25 08:10:35 dholland Exp $ */ +/* $NetBSD: kttcp.c,v 1.36 2014/08/05 07:55:31 rtr Exp $ */ /* * Copyright (c) 2002 Wasabi Systems, Inc. @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.35 2014/07/25 08:10:35 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.36 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -324,8 +324,8 @@ nopages: error = (*so->so_proto->pr_usrreqs->pr_sendoob)(so, top, NULL); else - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_SEND, top, NULL, NULL, l); + error = (*so->so_proto->pr_usrreqs->pr_send)(so, + top, NULL, NULL, l); if (dontroute) so->so_options &= ~SO_DONTROUTE; if (resid > 0) Index: src/sys/dev/bluetooth/bthidev.c diff -u src/sys/dev/bluetooth/bthidev.c:1.28 src/sys/dev/bluetooth/bthidev.c:1.29 --- src/sys/dev/bluetooth/bthidev.c:1.28 Thu Jul 31 03:39:35 2014 +++ src/sys/dev/bluetooth/bthidev.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: bthidev.c,v 1.28 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: bthidev.c,v 1.29 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.28 2014/07/31 03:39:35 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.29 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/condvar.h> @@ -1017,7 +1017,7 @@ bthidev_output(struct bthidev *hidev, ui m->m_pkthdr.len = m->m_len = rlen + 2; mutex_enter(bt_lock); - err = l2cap_send(sc->sc_int, m); + err = l2cap_send_pcb(sc->sc_int, m); mutex_exit(bt_lock); return err; Index: src/sys/dev/bluetooth/btmagic.c diff -u src/sys/dev/bluetooth/btmagic.c:1.10 src/sys/dev/bluetooth/btmagic.c:1.11 --- src/sys/dev/bluetooth/btmagic.c:1.10 Thu Jul 31 03:39:35 2014 +++ src/sys/dev/bluetooth/btmagic.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: btmagic.c,v 1.10 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: btmagic.c,v 1.11 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -85,7 +85,7 @@ *****************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.10 2014/07/31 03:39:35 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.11 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/conf.h> @@ -723,7 +723,7 @@ btmagic_ctl_send(struct btmagic_softc *s memcpy(mtod(m, uint8_t *), data, len); m->m_pkthdr.len = m->m_len = len; - return l2cap_send(sc->sc_ctl, m); + return l2cap_send_pcb(sc->sc_ctl, m); } /* Index: src/sys/dev/bluetooth/btsco.c diff -u src/sys/dev/bluetooth/btsco.c:1.32 src/sys/dev/bluetooth/btsco.c:1.33 --- src/sys/dev/bluetooth/btsco.c:1.32 Thu Jul 31 03:39:35 2014 +++ src/sys/dev/bluetooth/btsco.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: btsco.c,v 1.32 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: btsco.c,v 1.33 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.32 2014/07/31 03:39:35 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.33 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/audioio.h> @@ -1123,7 +1123,7 @@ btsco_dev_ioctl(void *hdl, u_long cmd, v /* * Our transmit interrupt. This is triggered when a new block is to be * sent. We send mtu sized chunks of the block as mbufs with external - * storage to sco_send() + * storage to sco_send_pcb() */ static void btsco_intr(void *arg) @@ -1163,7 +1163,7 @@ btsco_intr(void *arg) m->m_pkthdr.len = m->m_len = mlen; sc->sc_tx_pending++; - if (sco_send(sc->sc_sco, m) > 0) { + if (sco_send_pcb(sc->sc_sco, m) > 0) { sc->sc_tx_pending--; break; } Index: src/sys/kern/uipc_socket.c diff -u src/sys/kern/uipc_socket.c:1.231 src/sys/kern/uipc_socket.c:1.232 --- src/sys/kern/uipc_socket.c:1.231 Tue Aug 5 05:24:26 2014 +++ src/sys/kern/uipc_socket.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.231 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.232 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.231 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.232 2014/08/05 07:55:31 rtr Exp $"); #include "opt_compat_netbsd.h" #include "opt_sock_counters.h" @@ -1052,8 +1052,8 @@ sosend(struct socket *so, struct mbuf *a error = (*so->so_proto->pr_usrreqs->pr_sendoob)(so, top, control); else - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_SEND, top, addr, control, curlwp); + error = (*so->so_proto->pr_usrreqs->pr_send)(so, + top, addr, control, l); if (dontroute) so->so_options &= ~SO_DONTROUTE; if (resid > 0) Index: src/sys/kern/uipc_usrreq.c diff -u src/sys/kern/uipc_usrreq.c:1.165 src/sys/kern/uipc_usrreq.c:1.166 --- src/sys/kern/uipc_usrreq.c:1.165 Tue Aug 5 05:24:26 2014 +++ src/sys/kern/uipc_usrreq.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_usrreq.c,v 1.165 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: uipc_usrreq.c,v 1.166 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc. @@ -96,7 +96,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.165 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.166 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -377,6 +377,134 @@ unp_recvoob(struct socket *so, struct mb } static int +unp_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct unpcb *unp = sotounpcb(so); + int error = 0; + u_int newhiwat; + struct socket *so2; + + KASSERT(solocked(so)); + KASSERT(unp != NULL); + KASSERT(m != NULL); + + /* + * Note: unp_internalize() rejects any control message + * other than SCM_RIGHTS, and only allows one. This + * has the side-effect of preventing a caller from + * forging SCM_CREDS. + */ + if (control) { + sounlock(so); + error = unp_internalize(&control); + solock(so); + if (error != 0) { + m_freem(control); + m_freem(m); + return error; + } + } + + switch (so->so_type) { + + case SOCK_DGRAM: { + KASSERT(so->so_lock == uipc_lock); + if (nam) { + if ((so->so_state & SS_ISCONNECTED) != 0) + error = EISCONN; + else { + /* + * Note: once connected, the + * socket's lock must not be + * dropped until we have sent + * the message and disconnected. + * This is necessary to prevent + * intervening control ops, like + * another connection. + */ + error = unp_connect(so, nam, l); + } + } else { + if ((so->so_state & SS_ISCONNECTED) == 0) + error = ENOTCONN; + } + if (error) { + unp_dispose(control); + m_freem(control); + m_freem(m); + return error; + } + error = unp_output(m, control, unp); + if (nam) + unp_disconnect1(unp); + break; + } + + case SOCK_SEQPACKET: /* FALLTHROUGH */ + case SOCK_STREAM: +#define rcv (&so2->so_rcv) +#define snd (&so->so_snd) + if (unp->unp_conn == NULL) { + error = ENOTCONN; + break; + } + so2 = unp->unp_conn->unp_socket; + KASSERT(solocked2(so, so2)); + if (unp->unp_conn->unp_flags & UNP_WANTCRED) { + /* + * Credentials are passed only once on + * SOCK_STREAM and SOCK_SEQPACKET. + */ + unp->unp_conn->unp_flags &= ~UNP_WANTCRED; + control = unp_addsockcred(l, control); + } + /* + * Send to paired receive port, and then reduce + * send buffer hiwater marks to maintain backpressure. + * Wake up readers. + */ + if (control) { + if (sbappendcontrol(rcv, m, control) != 0) + control = NULL; + } else { + switch(so->so_type) { + case SOCK_SEQPACKET: + sbappendrecord(rcv, m); + break; + case SOCK_STREAM: + sbappend(rcv, m); + break; + default: + panic("uipc_usrreq"); + break; + } + } + snd->sb_mbmax -= + rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt; + unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt; + newhiwat = snd->sb_hiwat - + (rcv->sb_cc - unp->unp_conn->unp_cc); + (void)chgsbsize(so->so_uidinfo, + &snd->sb_hiwat, newhiwat, RLIM_INFINITY); + unp->unp_conn->unp_cc = rcv->sb_cc; + sorwakeup(so2); +#undef snd +#undef rcv + if (control != NULL) { + unp_dispose(control); + m_freem(control); + } + break; + + default: + panic("uipc 4"); + } + + return error; +} + +static int unp_sendoob(struct socket *so, struct mbuf *m, struct mbuf * control) { KASSERT(solocked(so)); @@ -410,12 +538,13 @@ unp_usrreq(struct socket *so, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); KASSERT(solocked(so)); unp = sotounpcb(so); - KASSERT(!control || req == PRU_SEND); + KASSERT(!control); if (unp == NULL) { error = EINVAL; goto release; @@ -461,120 +590,6 @@ unp_usrreq(struct socket *so, int req, s } break; - case PRU_SEND: - /* - * Note: unp_internalize() rejects any control message - * other than SCM_RIGHTS, and only allows one. This - * has the side-effect of preventing a caller from - * forging SCM_CREDS. - */ - if (control) { - sounlock(so); - error = unp_internalize(&control); - solock(so); - if (error != 0) { - m_freem(control); - m_freem(m); - break; - } - } - switch (so->so_type) { - - case SOCK_DGRAM: { - KASSERT(so->so_lock == uipc_lock); - if (nam) { - if ((so->so_state & SS_ISCONNECTED) != 0) - error = EISCONN; - else { - /* - * Note: once connected, the - * socket's lock must not be - * dropped until we have sent - * the message and disconnected. - * This is necessary to prevent - * intervening control ops, like - * another connection. - */ - error = unp_connect(so, nam, l); - } - } else { - if ((so->so_state & SS_ISCONNECTED) == 0) - error = ENOTCONN; - } - if (error) { - unp_dispose(control); - m_freem(control); - m_freem(m); - break; - } - KASSERT(l != NULL); - error = unp_output(m, control, unp); - if (nam) - unp_disconnect1(unp); - break; - } - - case SOCK_SEQPACKET: /* FALLTHROUGH */ - case SOCK_STREAM: -#define rcv (&so2->so_rcv) -#define snd (&so->so_snd) - if (unp->unp_conn == NULL) { - error = ENOTCONN; - break; - } - so2 = unp->unp_conn->unp_socket; - KASSERT(solocked2(so, so2)); - if (unp->unp_conn->unp_flags & UNP_WANTCRED) { - /* - * Credentials are passed only once on - * SOCK_STREAM and SOCK_SEQPACKET. - */ - unp->unp_conn->unp_flags &= ~UNP_WANTCRED; - control = unp_addsockcred(l, control); - } - /* - * Send to paired receive port, and then reduce - * send buffer hiwater marks to maintain backpressure. - * Wake up readers. - */ - if (control) { - if (sbappendcontrol(rcv, m, control) != 0) - control = NULL; - } else { - switch(so->so_type) { - case SOCK_SEQPACKET: - sbappendrecord(rcv, m); - break; - case SOCK_STREAM: - sbappend(rcv, m); - break; - default: - panic("uipc_usrreq"); - break; - } - } - snd->sb_mbmax -= - rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt; - unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt; - newhiwat = snd->sb_hiwat - - (rcv->sb_cc - unp->unp_conn->unp_cc); - (void)chgsbsize(so->so_uidinfo, - &snd->sb_hiwat, newhiwat, RLIM_INFINITY); - unp->unp_conn->unp_cc = rcv->sb_cc; - sorwakeup(so2); -#undef snd -#undef rcv - if (control != NULL) { - unp_dispose(control); - m_freem(control); - } - break; - - default: - panic("uipc 4"); - } - break; - default: panic("piusrreq"); } @@ -1911,6 +1926,7 @@ const struct pr_usrreqs unp_usrreqs = { .pr_peeraddr = unp_peeraddr, .pr_sockaddr = unp_sockaddr, .pr_recvoob = unp_recvoob, + .pr_send = unp_send, .pr_sendoob = unp_sendoob, .pr_generic = unp_usrreq, }; Index: src/sys/net/if_gre.c diff -u src/sys/net/if_gre.c:1.157 src/sys/net/if_gre.c:1.158 --- src/sys/net/if_gre.c:1.157 Wed Jul 9 04:54:03 2014 +++ src/sys/net/if_gre.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: if_gre.c,v 1.157 2014/07/09 04:54:03 rtr Exp $ */ +/* $NetBSD: if_gre.c,v 1.158 2014/08/05 07:55:31 rtr Exp $ */ /* * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. @@ -45,7 +45,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.157 2014/07/09 04:54:03 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.158 2014/08/05 07:55:31 rtr Exp $"); #include "opt_atalk.h" #include "opt_gre.h" @@ -528,8 +528,8 @@ gre_sosend(struct socket *so, struct mbu */ if (so->so_state & SS_CANTSENDMORE) snderr(EPIPE); - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_SEND, top, NULL, NULL, l); + error = (*so->so_proto->pr_usrreqs->pr_send)(so, + top, NULL, NULL, l); top = NULL; release: sbunlock(&so->so_snd); Index: src/sys/net/link_proto.c diff -u src/sys/net/link_proto.c:1.21 src/sys/net/link_proto.c:1.22 --- src/sys/net/link_proto.c:1.21 Tue Aug 5 05:24:26 2014 +++ src/sys/net/link_proto.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: link_proto.c,v 1.21 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: link_proto.c,v 1.22 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 1982, 1986, 1993 @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: link_proto.c,v 1.21 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: link_proto.c,v 1.22 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/socket.h> @@ -62,6 +62,8 @@ static int link_stat(struct socket *, st static int link_peeraddr(struct socket *, struct mbuf *); static int link_sockaddr(struct socket *, struct mbuf *); static int link_recvoob(struct socket *, struct mbuf *, int); +static int link_send(struct socket *, struct mbuf *, struct mbuf *, + struct mbuf *, struct lwp *); static int link_sendoob(struct socket *, struct mbuf *, struct mbuf *); static int link_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *); @@ -88,6 +90,7 @@ static const struct pr_usrreqs link_usrr .pr_peeraddr = link_peeraddr, .pr_sockaddr = link_sockaddr, .pr_recvoob = link_recvoob, + .pr_send = link_send, .pr_sendoob = link_sendoob, .pr_generic = link_usrreq, }; @@ -351,6 +354,15 @@ link_recvoob(struct socket *so, struct m } static int +link_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + KASSERT(solocked(so)); + + return EOPNOTSUPP; +} + +static int link_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -376,6 +388,7 @@ link_usrreq(struct socket *so, int req, KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); return EOPNOTSUPP; Index: src/sys/net/raw_cb.h diff -u src/sys/net/raw_cb.h:1.22 src/sys/net/raw_cb.h:1.23 --- src/sys/net/raw_cb.h:1.22 Wed May 21 20:43:56 2014 +++ src/sys/net/raw_cb.h Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_cb.h,v 1.22 2014/05/21 20:43:56 rmind Exp $ */ +/* $NetBSD: raw_cb.h,v 1.23 2014/08/05 07:55:31 rtr Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -70,6 +70,8 @@ int raw_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *); void raw_setsockaddr(struct rawcb *, struct mbuf *); void raw_setpeeraddr(struct rawcb *, struct mbuf *); +int raw_send(struct socket *, + struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *); #endif /* _KERNEL */ Index: src/sys/net/raw_usrreq.c diff -u src/sys/net/raw_usrreq.c:1.49 src/sys/net/raw_usrreq.c:1.50 --- src/sys/net/raw_usrreq.c:1.49 Tue Aug 5 05:24:26 2014 +++ src/sys/net/raw_usrreq.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_usrreq.c,v 1.49 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: raw_usrreq.c,v 1.50 2014/08/05 07:55:31 rtr Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.49 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.50 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/mbuf.h> @@ -154,6 +154,48 @@ raw_setpeeraddr(struct rawcb *rp, struct } int +raw_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct rawcb *rp = sotorawcb(so); + int error = 0; + + KASSERT(rp != NULL); + + /* + * Ship a packet out. The appropriate raw output + * routine handles any massaging necessary. + */ + if (control && control->m_len) { + m_freem(control); + m_freem(m); + return EINVAL; + } + if (nam) { + if ((so->so_state & SS_ISCONNECTED) != 0) { + error = EISCONN; + goto die; + } + error = (*so->so_proto->pr_usrreqs->pr_connect)(so, nam, l); + if (error) { + die: + m_freem(m); + return error; + } + } else { + if ((so->so_state & SS_ISCONNECTED) == 0) { + error = ENOTCONN; + goto die; + } + } + error = (*so->so_proto->pr_output)(m, so); + if (nam) + raw_disconnect(rp); + + return error; +} + +int raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l) { @@ -174,12 +216,13 @@ raw_usrreq(struct socket *so, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); s = splsoftnet(); KERNEL_LOCK(1, NULL); - KASSERT(!control || req == PRU_SEND); + KASSERT(!control); if (rp == NULL) { error = EINVAL; goto release; @@ -200,39 +243,6 @@ raw_usrreq(struct socket *so, int req, s error = EOPNOTSUPP; break; - /* - * Ship a packet out. The appropriate raw output - * routine handles any massaging necessary. - */ - case PRU_SEND: - if (control && control->m_len) { - m_freem(control); - m_freem(m); - error = EINVAL; - break; - } - if (nam) { - if ((so->so_state & SS_ISCONNECTED) != 0) { - error = EISCONN; - goto die; - } - error = (*so->so_proto->pr_usrreqs->pr_connect)(so, nam, l); - if (error) { - die: - m_freem(m); - break; - } - } else { - if ((so->so_state & SS_ISCONNECTED) == 0) { - error = ENOTCONN; - goto die; - } - } - error = (*so->so_proto->pr_output)(m, so); - if (nam) - raw_disconnect(rp); - break; - default: panic("raw_usrreq"); } Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.160 src/sys/net/rtsock.c:1.161 --- src/sys/net/rtsock.c:1.160 Tue Aug 5 05:24:26 2014 +++ src/sys/net/rtsock.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.160 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: rtsock.c,v 1.161 2014/08/05 07:55:31 rtr Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.160 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.161 2014/08/05 07:55:31 rtr Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -356,6 +356,22 @@ COMPATNAME(route_recvoob)(struct socket } static int +COMPATNAME(route_send)(struct socket *so, struct mbuf *m, + struct mbuf *nam, struct mbuf *control, struct lwp *l) +{ + int error = 0; + int s; + + KASSERT(solocked(so)); + + s = splsoftnet(); + error = raw_send(so, m, nam, control, l); + splx(s); + + return error; +} + +static int COMPATNAME(route_sendoob)(struct socket *so, struct mbuf *m, struct mbuf *control) { @@ -387,6 +403,7 @@ COMPATNAME(route_usrreq)(struct socket * KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); s = splsoftnet(); @@ -1496,6 +1513,7 @@ static const struct pr_usrreqs route_usr .pr_peeraddr = COMPATNAME(route_peeraddr_wrapper), .pr_sockaddr = COMPATNAME(route_sockaddr_wrapper), .pr_recvoob = COMPATNAME(route_recvoob_wrapper), + .pr_send = COMPATNAME(route_send_wrapper), .pr_sendoob = COMPATNAME(route_sendoob_wrapper), .pr_generic = COMPATNAME(route_usrreq_wrapper), }; Index: src/sys/netatalk/ddp_usrreq.c diff -u src/sys/netatalk/ddp_usrreq.c:1.58 src/sys/netatalk/ddp_usrreq.c:1.59 --- src/sys/netatalk/ddp_usrreq.c:1.58 Tue Aug 5 05:24:26 2014 +++ src/sys/netatalk/ddp_usrreq.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ddp_usrreq.c,v 1.58 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: ddp_usrreq.c,v 1.59 2014/08/05 07:55:31 rtr Exp $ */ /* * Copyright (c) 1990,1991 Regents of The University of Michigan. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.58 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.59 2014/08/05 07:55:31 rtr Exp $"); #include "opt_mbuftrace.h" @@ -96,6 +96,7 @@ ddp_usrreq(struct socket *so, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); ddp = sotoddpcb(so); @@ -115,36 +116,6 @@ ddp_usrreq(struct socket *so, int req, s goto release; } switch (req) { - case PRU_SEND:{ - int s = 0; - - if (addr) { - if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) { - error = EISCONN; - break; - } - s = splnet(); - error = at_pcbconnect(ddp, addr); - if (error) { - splx(s); - break; - } - } else { - if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT) { - error = ENOTCONN; - break; - } - } - - error = ddp_output(m, ddp); - m = NULL; - if (addr) { - at_pcbdisconnect(ddp); - splx(s); - } - } - break; - case PRU_CONNECT2: case PRU_FASTTIMO: case PRU_SLOWTIMO: @@ -565,6 +536,42 @@ ddp_recvoob(struct socket *so, struct mb } static int +ddp_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct ddpcb *ddp = sotoddpcb(so); + int error = 0; + int s; + + KASSERT(solocked(so)); + KASSERT(ddp != NULL); + KASSERT(nam != NULL); + + if (nam) { + if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) + return EISCONN; + s = splnet(); + error = at_pcbconnect(ddp, nam); + if (error) { + splx(s); + return error; + } + } else { + if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT) + return ENOTCONN; + } + + error = ddp_output(m, ddp); + m = NULL; + if (nam) { + at_pcbdisconnect(ddp); + splx(s); + } + + return error; +} + +static int ddp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -660,6 +667,7 @@ PR_WRAP_USRREQS(ddp) #define ddp_peeraddr ddp_peeraddr_wrapper #define ddp_sockaddr ddp_sockaddr_wrapper #define ddp_recvoob ddp_recvoob_wrapper +#define ddp_send ddp_send_wrapper #define ddp_sendoob ddp_sendoob_wrapper #define ddp_usrreq ddp_usrreq_wrapper @@ -678,6 +686,7 @@ const struct pr_usrreqs ddp_usrreqs = { .pr_peeraddr = ddp_peeraddr, .pr_sockaddr = ddp_sockaddr, .pr_recvoob = ddp_recvoob, + .pr_send = ddp_send, .pr_sendoob = ddp_sendoob, .pr_generic = ddp_usrreq, }; Index: src/sys/netbt/hci_socket.c diff -u src/sys/netbt/hci_socket.c:1.37 src/sys/netbt/hci_socket.c:1.38 --- src/sys/netbt/hci_socket.c:1.37 Tue Aug 5 05:24:26 2014 +++ src/sys/netbt/hci_socket.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: hci_socket.c,v 1.37 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: hci_socket.c,v 1.38 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.37 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.38 2014/08/05 07:55:31 rtr Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG @@ -353,7 +353,7 @@ hci_cmdwait_flush(struct socket *so) * This came from userland, so check it out. */ static int -hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr) +hci_send_pcb(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr) { struct hci_unit *unit; struct mbuf *m0; @@ -655,6 +655,43 @@ hci_recvoob(struct socket *so, struct mb } static int +hci_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct hci_pcb *pcb = so->so_pcb; + struct sockaddr_bt * sa = NULL; + int err = 0; + + KASSERT(solocked(so)); + KASSERT(pcb != NULL); + + if (control) /* have no use for this */ + m_freem(control); + + if (nam) { + sa = mtod(nam, struct sockaddr_bt *); + + if (sa->bt_len != sizeof(struct sockaddr_bt)) { + err = EINVAL; + goto release; + } + + if (sa->bt_family != AF_BLUETOOTH) { + err = EAFNOSUPPORT; + goto release; + } + } + + return hci_send_pcb(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr)); + +release: + if (m) + m_freem(m); + + return err; +} + +static int hci_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -682,7 +719,6 @@ hci_usrreq(struct socket *up, int req, s struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb; - struct sockaddr_bt *sa; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); @@ -700,6 +736,7 @@ hci_usrreq(struct socket *up, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); switch(req) { @@ -714,27 +751,6 @@ hci_usrreq(struct socket *up, int req, s } switch(req) { - case PRU_SEND: - sa = NULL; - if (nam) { - sa = mtod(nam, struct sockaddr_bt *); - - if (sa->bt_len != sizeof(struct sockaddr_bt)) { - err = EINVAL; - goto release; - } - - if (sa->bt_family != AF_BLUETOOTH) { - err = EAFNOSUPPORT; - goto release; - } - } - - if (ctl) /* have no use for this */ - m_freem(ctl); - - return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr)); - case PRU_RCVD: return EOPNOTSUPP; /* (no release) */ @@ -980,6 +996,7 @@ PR_WRAP_USRREQS(hci) #define hci_peeraddr hci_peeraddr_wrapper #define hci_sockaddr hci_sockaddr_wrapper #define hci_recvoob hci_recvoob_wrapper +#define hci_send hci_send_wrapper #define hci_sendoob hci_sendoob_wrapper #define hci_usrreq hci_usrreq_wrapper @@ -998,6 +1015,7 @@ const struct pr_usrreqs hci_usrreqs = { .pr_peeraddr = hci_peeraddr, .pr_sockaddr = hci_sockaddr, .pr_recvoob = hci_recvoob, + .pr_send = hci_send, .pr_sendoob = hci_sendoob, .pr_generic = hci_usrreq, }; Index: src/sys/netbt/l2cap.h diff -u src/sys/netbt/l2cap.h:1.17 src/sys/netbt/l2cap.h:1.18 --- src/sys/netbt/l2cap.h:1.17 Thu Jul 31 03:39:35 2014 +++ src/sys/netbt/l2cap.h Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: l2cap.h,v 1.17 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: l2cap.h,v 1.18 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. @@ -54,7 +54,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: l2cap.h,v 1.17 2014/07/31 03:39:35 rtr Exp $ + * $Id: l2cap.h,v 1.18 2014/08/05 07:55:31 rtr Exp $ * $FreeBSD: src/sys/netgraph/bluetooth/include/l2cap.h,v 1.4 2005/08/31 18:13:23 emax Exp $ */ @@ -469,7 +469,7 @@ int l2cap_peeraddr_pcb(struct l2cap_chan int l2cap_disconnect_pcb(struct l2cap_channel *, int); void l2cap_detach_pcb(struct l2cap_channel **); int l2cap_listen_pcb(struct l2cap_channel *); -int l2cap_send(struct l2cap_channel *, struct mbuf *); +int l2cap_send_pcb(struct l2cap_channel *, struct mbuf *); int l2cap_setopt(struct l2cap_channel *, const struct sockopt *); int l2cap_getopt(struct l2cap_channel *, struct sockopt *); Index: src/sys/netbt/l2cap_upper.c diff -u src/sys/netbt/l2cap_upper.c:1.17 src/sys/netbt/l2cap_upper.c:1.18 --- src/sys/netbt/l2cap_upper.c:1.17 Thu Jul 31 03:39:35 2014 +++ src/sys/netbt/l2cap_upper.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: l2cap_upper.c,v 1.17 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: l2cap_upper.c,v 1.18 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.17 2014/07/31 03:39:35 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.18 2014/08/05 07:55:32 rtr Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -372,7 +372,7 @@ l2cap_listen_pcb(struct l2cap_channel *c } /* - * l2cap_send(l2cap_channel, mbuf) + * l2cap_send_pcb(l2cap_channel, mbuf) * * Output SDU on channel described by channel. This corresponds * to "Send Data Request" in the L2CAP specification. The upper @@ -394,7 +394,7 @@ l2cap_listen_pcb(struct l2cap_channel *c * B-Frame header and start sending if we are not already */ int -l2cap_send(struct l2cap_channel *chan, struct mbuf *m) +l2cap_send_pcb(struct l2cap_channel *chan, struct mbuf *m) { l2cap_hdr_t *hdr; int plen; Index: src/sys/netbt/l2cap_lower.c diff -u src/sys/netbt/l2cap_lower.c:1.9 src/sys/netbt/l2cap_lower.c:1.10 --- src/sys/netbt/l2cap_lower.c:1.9 Tue Aug 5 13:08:31 2008 +++ src/sys/netbt/l2cap_lower.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: l2cap_lower.c,v 1.9 2008/08/05 13:08:31 plunky Exp $ */ +/* $NetBSD: l2cap_lower.c,v 1.10 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: l2cap_lower.c,v 1.9 2008/08/05 13:08:31 plunky Exp $"); +__KERNEL_RCSID(0, "$NetBSD: l2cap_lower.c,v 1.10 2014/08/05 07:55:31 rtr Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -150,7 +150,7 @@ failed: } /* - * Start another L2CAP packet on its way. This is called from l2cap_send + * Start another L2CAP packet on its way. This is called from l2cap_send_pcb * (when no PDU is pending) and hci_acl_start (when PDU has been placed on * device queue). Thus we can have more than one PDU waiting at the device * if space is available but no single channel will hog the link. Index: src/sys/netbt/l2cap_socket.c diff -u src/sys/netbt/l2cap_socket.c:1.28 src/sys/netbt/l2cap_socket.c:1.29 --- src/sys/netbt/l2cap_socket.c:1.28 Tue Aug 5 05:24:26 2014 +++ src/sys/netbt/l2cap_socket.c Tue Aug 5 07:55:31 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: l2cap_socket.c,v 1.28 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: l2cap_socket.c,v 1.29 2014/08/05 07:55:31 rtr Exp $ */ /*- * Copyright (c) 2005 Iain Hibbert. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.28 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.29 2014/08/05 07:55:31 rtr Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG @@ -283,6 +283,49 @@ l2cap_recvoob(struct socket *so, struct } static int +l2cap_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct l2cap_channel *pcb = so->so_pcb; + struct mbuf *m0; + int error = 0; + + KASSERT(solocked(so)); + KASSERT(m != NULL); + + if (control) + m_freem(control); + + if (pcb == NULL) { + error = EINVAL; + goto release; + } + + if (m->m_pkthdr.len == 0) + goto release; + + if (m->m_pkthdr.len > pcb->lc_omtu) { + error = EMSGSIZE; + goto release; + } + + m0 = m_copypacket(m, M_DONTWAIT); + if (m0 == NULL) { + error = ENOMEM; + goto release; + } + + sbappendrecord(&so->so_snd, m); + return l2cap_send_pcb(pcb, m0); + +release: + if (m) + m_freem(m); + + return error; +} + +static int l2cap_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -315,7 +358,6 @@ l2cap_usrreq(struct socket *up, int req, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct l2cap_channel *pcb = up->so_pcb; - struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); @@ -333,6 +375,7 @@ l2cap_usrreq(struct socket *up, int req, KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); switch (req) { @@ -346,28 +389,6 @@ l2cap_usrreq(struct socket *up, int req, } switch(req) { - case PRU_SEND: - KASSERT(m != NULL); - if (m->m_pkthdr.len == 0) - break; - - if (m->m_pkthdr.len > pcb->lc_omtu) { - err = EMSGSIZE; - break; - } - - m0 = m_copypacket(m, M_DONTWAIT); - if (m0 == NULL) { - err = ENOMEM; - break; - } - - if (ctl) /* no use for that */ - m_freem(ctl); - - sbappendrecord(&up->so_snd, m); - return l2cap_send(pcb, m0); - case PRU_RCVD: return EOPNOTSUPP; /* (no release) */ @@ -547,6 +568,7 @@ PR_WRAP_USRREQS(l2cap) #define l2cap_peeraddr l2cap_peeraddr_wrapper #define l2cap_sockaddr l2cap_sockaddr_wrapper #define l2cap_recvoob l2cap_recvoob_wrapper +#define l2cap_send l2cap_send_wrapper #define l2cap_sendoob l2cap_sendoob_wrapper #define l2cap_usrreq l2cap_usrreq_wrapper @@ -565,6 +587,7 @@ const struct pr_usrreqs l2cap_usrreqs = .pr_peeraddr = l2cap_peeraddr, .pr_sockaddr = l2cap_sockaddr, .pr_recvoob = l2cap_recvoob, + .pr_send = l2cap_send, .pr_sendoob = l2cap_sendoob, .pr_generic = l2cap_usrreq, }; Index: src/sys/netbt/rfcomm.h diff -u src/sys/netbt/rfcomm.h:1.16 src/sys/netbt/rfcomm.h:1.17 --- src/sys/netbt/rfcomm.h:1.16 Thu Jul 31 03:39:35 2014 +++ src/sys/netbt/rfcomm.h Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: rfcomm.h,v 1.16 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: rfcomm.h,v 1.17 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -55,7 +55,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: rfcomm.h,v 1.16 2014/07/31 03:39:35 rtr Exp $ + * $Id: rfcomm.h,v 1.17 2014/08/05 07:55:32 rtr Exp $ * $FreeBSD: src/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h,v 1.4 2005/01/11 01:39:53 emax Exp $ */ @@ -415,7 +415,7 @@ int rfcomm_peeraddr_pcb(struct rfcomm_dl int rfcomm_disconnect_pcb(struct rfcomm_dlc *, int); void rfcomm_detach_pcb(struct rfcomm_dlc **); int rfcomm_listen_pcb(struct rfcomm_dlc *); -int rfcomm_send(struct rfcomm_dlc *, struct mbuf *); +int rfcomm_send_pcb(struct rfcomm_dlc *, struct mbuf *); int rfcomm_rcvd(struct rfcomm_dlc *, size_t); int rfcomm_setopt(struct rfcomm_dlc *, const struct sockopt *); int rfcomm_getopt(struct rfcomm_dlc *, struct sockopt *); Index: src/sys/netbt/rfcomm_session.c diff -u src/sys/netbt/rfcomm_session.c:1.22 src/sys/netbt/rfcomm_session.c:1.23 --- src/sys/netbt/rfcomm_session.c:1.22 Thu Jul 31 03:39:35 2014 +++ src/sys/netbt/rfcomm_session.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: rfcomm_session.c,v 1.22 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: rfcomm_session.c,v 1.23 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.22 2014/07/31 03:39:35 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.23 2014/08/05 07:55:32 rtr Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -1510,7 +1510,7 @@ rfcomm_session_send_frame(struct rfcomm_ DPRINTFN(5, "dlci %d type %2.2x (%d bytes, fcs=%#2.2x)\n", dlci, type, m->m_pkthdr.len, fcs); - return l2cap_send(rs->rs_l2cap, m); + return l2cap_send_pcb(rs->rs_l2cap, m); } /* @@ -1610,7 +1610,7 @@ rfcomm_session_send_uih(struct rfcomm_se /* * UIH frame ready to go.. */ - err = l2cap_send(rs->rs_l2cap, m0); + err = l2cap_send_pcb(rs->rs_l2cap, m0); if (err) goto fail; Index: src/sys/netbt/rfcomm_socket.c diff -u src/sys/netbt/rfcomm_socket.c:1.30 src/sys/netbt/rfcomm_socket.c:1.31 --- src/sys/netbt/rfcomm_socket.c:1.30 Tue Aug 5 05:24:26 2014 +++ src/sys/netbt/rfcomm_socket.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: rfcomm_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: rfcomm_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG @@ -291,6 +291,39 @@ rfcomm_recvoob(struct socket *so, struct } static int +rfcomm_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct rfcomm_dlc *pcb = so->so_pcb; + int err = 0; + struct mbuf *m0; + + KASSERT(solocked(so)); + KASSERT(m != NULL); + + if (control) /* no use for that */ + m_freem(control); + + if (pcb == NULL) { + err = EINVAL; + goto release; + } + + m0 = m_copypacket(m, M_DONTWAIT); + if (m0 == NULL) { + err = ENOMEM; + goto release; + } + + sbappendstream(&so->so_snd, m); + return rfcomm_send_pcb(pcb, m0); + +release: + m_freem(m); + return err; +} + +static int rfcomm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -323,7 +356,6 @@ rfcomm_usrreq(struct socket *up, int req struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct rfcomm_dlc *pcb = up->so_pcb; - struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); @@ -341,6 +373,7 @@ rfcomm_usrreq(struct socket *up, int req KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); switch (req) { @@ -353,22 +386,6 @@ rfcomm_usrreq(struct socket *up, int req } switch(req) { - case PRU_SEND: - KASSERT(m != NULL); - - if (ctl) /* no use for that */ - m_freem(ctl); - - m0 = m_copypacket(m, M_DONTWAIT); - if (m0 == NULL) { - err = ENOMEM; - goto release; - } - - sbappendstream(&up->so_snd, m); - - return rfcomm_send(pcb, m0); - case PRU_RCVD: return rfcomm_rcvd(pcb, sbspace(&up->so_rcv)); @@ -560,6 +577,7 @@ PR_WRAP_USRREQS(rfcomm) #define rfcomm_peeraddr rfcomm_peeraddr_wrapper #define rfcomm_sockaddr rfcomm_sockaddr_wrapper #define rfcomm_recvoob rfcomm_recvoob_wrapper +#define rfcomm_send rfcomm_send_wrapper #define rfcomm_sendoob rfcomm_sendoob_wrapper #define rfcomm_usrreq rfcomm_usrreq_wrapper @@ -578,6 +596,7 @@ const struct pr_usrreqs rfcomm_usrreqs = .pr_peeraddr = rfcomm_peeraddr, .pr_sockaddr = rfcomm_sockaddr, .pr_recvoob = rfcomm_recvoob, + .pr_send = rfcomm_send, .pr_sendoob = rfcomm_sendoob, .pr_generic = rfcomm_usrreq, }; Index: src/sys/netbt/sco_socket.c diff -u src/sys/netbt/sco_socket.c:1.30 src/sys/netbt/sco_socket.c:1.31 --- src/sys/netbt/sco_socket.c:1.30 Tue Aug 5 05:24:26 2014 +++ src/sys/netbt/sco_socket.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sco_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: sco_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $"); /* load symbolic names */ #ifdef BLUETOOTH_DEBUG @@ -274,6 +274,47 @@ sco_recvoob(struct socket *so, struct mb } static int +sco_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct sco_pcb *pcb = so->so_pcb; + int err = 0; + struct mbuf *m0; + + KASSERT(solocked(so)); + KASSERT(m != NULL); + + if (control) /* no use for that */ + m_freem(control); + + if (pcb == NULL) { + err = EINVAL; + goto release; + } + + if (m->m_pkthdr.len == 0) + goto release; + + if (m->m_pkthdr.len > pcb->sp_mtu) { + err = EMSGSIZE; + goto release; + } + + m0 = m_copypacket(m, M_DONTWAIT); + if (m0 == NULL) { + err = ENOMEM; + goto release; + } + + sbappendrecord(&so->so_snd, m); + return sco_send_pcb(pcb, m0); + +release: + m_freem(m); + return err; +} + +static int sco_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -302,7 +343,6 @@ sco_usrreq(struct socket *up, int req, s struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct sco_pcb *pcb = (struct sco_pcb *)up->so_pcb; - struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); @@ -320,6 +360,7 @@ sco_usrreq(struct socket *up, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); switch(req) { @@ -334,28 +375,6 @@ sco_usrreq(struct socket *up, int req, s } switch(req) { - case PRU_SEND: - KASSERT(m != NULL); - if (m->m_pkthdr.len == 0) - break; - - if (m->m_pkthdr.len > pcb->sp_mtu) { - err = EMSGSIZE; - break; - } - - m0 = m_copypacket(m, M_DONTWAIT); - if (m0 == NULL) { - err = ENOMEM; - break; - } - - if (ctl) /* no use for that */ - m_freem(ctl); - - sbappendrecord(&up->so_snd, m); - return sco_send(pcb, m0); - case PRU_RCVD: return EOPNOTSUPP; /* (no release) */ @@ -514,6 +533,7 @@ PR_WRAP_USRREQS(sco) #define sco_peeraddr sco_peeraddr_wrapper #define sco_sockaddr sco_sockaddr_wrapper #define sco_recvoob sco_recvoob_wrapper +#define sco_send sco_send_wrapper #define sco_sendoob sco_sendoob_wrapper #define sco_usrreq sco_usrreq_wrapper @@ -532,6 +552,7 @@ const struct pr_usrreqs sco_usrreqs = { .pr_peeraddr = sco_peeraddr, .pr_sockaddr = sco_sockaddr, .pr_recvoob = sco_recvoob, + .pr_send = sco_send, .pr_sendoob = sco_sendoob, .pr_generic = sco_usrreq, }; Index: src/sys/netbt/rfcomm_upper.c diff -u src/sys/netbt/rfcomm_upper.c:1.19 src/sys/netbt/rfcomm_upper.c:1.20 --- src/sys/netbt/rfcomm_upper.c:1.19 Thu Jul 31 03:39:35 2014 +++ src/sys/netbt/rfcomm_upper.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: rfcomm_upper.c,v 1.19 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: rfcomm_upper.c,v 1.20 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.19 2014/07/31 03:39:35 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.20 2014/08/05 07:55:32 rtr Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -382,14 +382,14 @@ rfcomm_listen_pcb(struct rfcomm_dlc *dlc } /* - * rfcomm_send(dlc, mbuf) + * rfcomm_send_pcb(dlc, mbuf) * * Output data on DLC. This is streamed data, so we add it * to our buffer and start the DLC, which will assemble * packets and send them if it can. */ int -rfcomm_send(struct rfcomm_dlc *dlc, struct mbuf *m) +rfcomm_send_pcb(struct rfcomm_dlc *dlc, struct mbuf *m) { if (dlc->rd_txbuf != NULL) { Index: src/sys/netbt/sco.h diff -u src/sys/netbt/sco.h:1.10 src/sys/netbt/sco.h:1.11 --- src/sys/netbt/sco.h:1.10 Thu Jul 31 03:39:35 2014 +++ src/sys/netbt/sco.h Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sco.h,v 1.10 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: sco.h,v 1.11 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -76,7 +76,7 @@ int sco_peeraddr_pcb(struct sco_pcb *, s int sco_disconnect_pcb(struct sco_pcb *, int); void sco_detach_pcb(struct sco_pcb **); int sco_listen_pcb(struct sco_pcb *); -int sco_send(struct sco_pcb *, struct mbuf *); +int sco_send_pcb(struct sco_pcb *, struct mbuf *); int sco_setopt(struct sco_pcb *, const struct sockopt *); int sco_getopt(struct sco_pcb *, struct sockopt *); Index: src/sys/netbt/sco_upper.c diff -u src/sys/netbt/sco_upper.c:1.15 src/sys/netbt/sco_upper.c:1.16 --- src/sys/netbt/sco_upper.c:1.15 Thu Jul 31 03:39:35 2014 +++ src/sys/netbt/sco_upper.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sco_upper.c,v 1.15 2014/07/31 03:39:35 rtr Exp $ */ +/* $NetBSD: sco_upper.c,v 1.16 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.15 2014/07/31 03:39:35 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.16 2014/08/05 07:55:32 rtr Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -261,7 +261,7 @@ sco_listen_pcb(struct sco_pcb *pcb) } /* - * sco_send(pcb, mbuf) + * sco_send_pcb(pcb, mbuf) * * Send data on SCO pcb. * @@ -271,7 +271,7 @@ sco_listen_pcb(struct sco_pcb *pcb) * we can drop a record from the socket buffer. */ int -sco_send(struct sco_pcb *pcb, struct mbuf *m) +sco_send_pcb(struct sco_pcb *pcb, struct mbuf *m) { hci_scodata_hdr_t *hdr; int plen; Index: src/sys/netinet/raw_ip.c diff -u src/sys/netinet/raw_ip.c:1.142 src/sys/netinet/raw_ip.c:1.143 --- src/sys/netinet/raw_ip.c:1.142 Tue Aug 5 05:24:26 2014 +++ src/sys/netinet/raw_ip.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip.c,v 1.142 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: raw_ip.c,v 1.143 2014/08/05 07:55:32 rtr Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.142 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.143 2014/08/05 07:55:32 rtr Exp $"); #include "opt_inet.h" #include "opt_compat_netbsd.h" @@ -723,6 +723,55 @@ rip_recvoob(struct socket *so, struct mb } static int +rip_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct inpcb *inp = sotoinpcb(so); + int error = 0; + int s; + + KASSERT(solocked(so)); + KASSERT(inp != NULL); + KASSERT(m != NULL); + + /* + * Ship a packet out. The appropriate raw output + * routine handles any massaging necessary. + */ + if (control && control->m_len) { + m_freem(control); + m_freem(m); + return EINVAL; + } + + s = splsoftnet(); + if (nam) { + if ((so->so_state & SS_ISCONNECTED) != 0) { + error = EISCONN; + goto die; + } + error = rip_connect_pcb(inp, nam); + if (error) { + die: + m_freem(m); + splx(s); + return error; + } + } else { + if ((so->so_state & SS_ISCONNECTED) == 0) { + error = ENOTCONN; + goto die; + } + } + error = rip_output(m, inp); + if (nam) + rip_disconnect1(inp); + + splx(s); + return error; +} + +static int rip_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -754,6 +803,7 @@ rip_usrreq(struct socket *so, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); s = splsoftnet(); @@ -770,7 +820,7 @@ rip_usrreq(struct socket *so, int req, s KASSERT(solocked(so)); inp = sotoinpcb(so); - KASSERT(!control || (req == PRU_SEND)); + KASSERT(!control); if (inp == NULL) { splx(s); return EINVAL; @@ -786,41 +836,6 @@ rip_usrreq(struct socket *so, int req, s error = EOPNOTSUPP; break; - /* - * Ship a packet out. The appropriate raw output - * routine handles any massaging necessary. - */ - case PRU_SEND: - if (control && control->m_len) { - m_freem(control); - m_freem(m); - error = EINVAL; - break; - } - { - if (nam) { - if ((so->so_state & SS_ISCONNECTED) != 0) { - error = EISCONN; - goto die; - } - error = rip_connect_pcb(inp, nam); - if (error) { - die: - m_freem(m); - break; - } - } else { - if ((so->so_state & SS_ISCONNECTED) == 0) { - error = ENOTCONN; - goto die; - } - } - error = rip_output(m, inp); - if (nam) - rip_disconnect1(inp); - } - break; - default: panic("rip_usrreq"); } @@ -844,6 +859,7 @@ PR_WRAP_USRREQS(rip) #define rip_peeraddr rip_peeraddr_wrapper #define rip_sockaddr rip_sockaddr_wrapper #define rip_recvoob rip_recvoob_wrapper +#define rip_send rip_send_wrapper #define rip_sendoob rip_sendoob_wrapper #define rip_usrreq rip_usrreq_wrapper @@ -862,6 +878,7 @@ const struct pr_usrreqs rip_usrreqs = { .pr_peeraddr = rip_peeraddr, .pr_sockaddr = rip_sockaddr, .pr_recvoob = rip_recvoob, + .pr_send = rip_send, .pr_sendoob = rip_sendoob, .pr_generic = rip_usrreq, }; Index: src/sys/netinet/tcp_usrreq.c diff -u src/sys/netinet/tcp_usrreq.c:1.197 src/sys/netinet/tcp_usrreq.c:1.198 --- src/sys/netinet/tcp_usrreq.c:1.197 Tue Aug 5 07:10:41 2014 +++ src/sys/netinet/tcp_usrreq.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_usrreq.c,v 1.197 2014/08/05 07:10:41 rtr Exp $ */ +/* $NetBSD: tcp_usrreq.c,v 1.198 2014/08/05 07:55:32 rtr Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -99,7 +99,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.197 2014/08/05 07:10:41 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.198 2014/08/05 07:55:32 rtr Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -245,6 +245,7 @@ tcp_usrreq(struct socket *so, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); s = splsoftnet(); @@ -283,7 +284,7 @@ tcp_usrreq(struct socket *so, int req, s ostate = tcp_debug_capture(tp, req); - KASSERT(!control || req == PRU_SEND); + KASSERT(!control); #ifdef INET6 /* XXX: KASSERT((inp != NULL) ^ (in6p != NULL)); */ #endif @@ -312,21 +313,6 @@ tcp_usrreq(struct socket *so, int req, s (void) tcp_output(tp); break; - /* - * Do a send by putting data in output queue and updating urgent - * marker if URG set. Possibly send more data. - */ - case PRU_SEND: - if (control && control->m_len) { - m_freem(control); - m_freem(m); - error = EINVAL; - break; - } - sbappendstream(&so->so_snd, m); - error = tcp_output(tp); - break; - default: panic("tcp_usrreq"); } @@ -1121,6 +1107,43 @@ tcp_recvoob(struct socket *so, struct mb } static int +tcp_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct inpcb *inp = NULL; + struct in6pcb *in6p = NULL; + struct tcpcb *tp = NULL; + int ostate = 0; + int error = 0; + int s; + + if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0) + return error; + + ostate = tcp_debug_capture(tp, PRU_SEND); + + /* + * Do a send by putting data in output queue and updating urgent + * marker if URG set. Possibly send more data. + */ + s = splsoftnet(); + if (control && control->m_len) { + m_freem(control); + m_freem(m); + tcp_debug_trace(so, tp, ostate, PRU_SEND); + splx(s); + return EINVAL; + } + + sbappendstream(&so->so_snd, m); + error = tcp_output(tp); + tcp_debug_trace(so, tp, ostate, PRU_SEND); + splx(s); + + return error; +} + +static int tcp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { struct inpcb *inp = NULL; @@ -2408,6 +2431,7 @@ PR_WRAP_USRREQS(tcp) #define tcp_peeraddr tcp_peeraddr_wrapper #define tcp_sockaddr tcp_sockaddr_wrapper #define tcp_recvoob tcp_recvoob_wrapper +#define tcp_send tcp_send_wrapper #define tcp_sendoob tcp_sendoob_wrapper #define tcp_usrreq tcp_usrreq_wrapper @@ -2426,6 +2450,7 @@ const struct pr_usrreqs tcp_usrreqs = { .pr_peeraddr = tcp_peeraddr, .pr_sockaddr = tcp_sockaddr, .pr_recvoob = tcp_recvoob, + .pr_send = tcp_send, .pr_sendoob = tcp_sendoob, .pr_generic = tcp_usrreq, }; Index: src/sys/netinet/udp_usrreq.c diff -u src/sys/netinet/udp_usrreq.c:1.214 src/sys/netinet/udp_usrreq.c:1.215 --- src/sys/netinet/udp_usrreq.c:1.214 Tue Aug 5 05:24:26 2014 +++ src/sys/netinet/udp_usrreq.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: udp_usrreq.c,v 1.214 2014/08/05 05:24:26 rtr Exp $ */ +/* $NetBSD: udp_usrreq.c,v 1.215 2014/08/05 07:55:32 rtr Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.214 2014/08/05 05:24:26 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.215 2014/08/05 07:55:32 rtr Exp $"); #include "opt_inet.h" #include "opt_compat_netbsd.h" @@ -1049,6 +1049,58 @@ udp_recvoob(struct socket *so, struct mb } static int +udp_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct inpcb *inp = sotoinpcb(so); + int error = 0; + struct in_addr laddr; /* XXX */ + int s; + + KASSERT(solocked(so)); + KASSERT(inp != NULL); + KASSERT(m != NULL); + + if (control && control->m_len) { + m_freem(control); + m_freem(m); + return EINVAL; + } + + memset(&laddr, 0, sizeof laddr); + + s = splsoftnet(); + if (nam) { + laddr = inp->inp_laddr; /* XXX */ + if ((so->so_state & SS_ISCONNECTED) != 0) { + error = EISCONN; + goto die; + } + error = in_pcbconnect(inp, nam, l); + if (error) + goto die; + } else { + if ((so->so_state & SS_ISCONNECTED) == 0) { + error = ENOTCONN; + goto die; + } + } + error = udp_output(m, inp); + m = NULL; + if (nam) { + in_pcbdisconnect(inp); + inp->inp_laddr = laddr; /* XXX */ + in_pcbstate(inp, INP_BOUND); /* XXX */ + } + die: + if (m) + m_freem(m); + + splx(s); + return error; +} + +static int udp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -1080,6 +1132,7 @@ udp_usrreq(struct socket *so, int req, s KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); s = splsoftnet(); @@ -1096,7 +1149,7 @@ udp_usrreq(struct socket *so, int req, s KASSERT(solocked(so)); inp = sotoinpcb(so); - KASSERT(!control || req == PRU_SEND); + KASSERT(!control); if (inp == NULL) { splx(s); return EINVAL; @@ -1115,45 +1168,6 @@ udp_usrreq(struct socket *so, int req, s error = EOPNOTSUPP; break; - case PRU_SEND: - if (control && control->m_len) { - m_freem(control); - m_freem(m); - error = EINVAL; - break; - } - { - struct in_addr laddr; /* XXX */ - - memset(&laddr, 0, sizeof laddr); - if (nam) { - laddr = inp->inp_laddr; /* XXX */ - if ((so->so_state & SS_ISCONNECTED) != 0) { - error = EISCONN; - goto die; - } - error = in_pcbconnect(inp, nam, l); - if (error) - goto die; - } else { - if ((so->so_state & SS_ISCONNECTED) == 0) { - error = ENOTCONN; - goto die; - } - } - error = udp_output(m, inp); - m = NULL; - if (nam) { - in_pcbdisconnect(inp); - inp->inp_laddr = laddr; /* XXX */ - in_pcbstate(inp, INP_BOUND); /* XXX */ - } - die: - if (m) - m_freem(m); - } - break; - default: panic("udp_usrreq"); } @@ -1394,6 +1408,7 @@ PR_WRAP_USRREQS(udp) #define udp_peeraddr udp_peeraddr_wrapper #define udp_sockaddr udp_sockaddr_wrapper #define udp_recvoob udp_recvoob_wrapper +#define udp_send udp_send_wrapper #define udp_sendoob udp_sendoob_wrapper #define udp_usrreq udp_usrreq_wrapper @@ -1412,6 +1427,7 @@ const struct pr_usrreqs udp_usrreqs = { .pr_peeraddr = udp_peeraddr, .pr_sockaddr = udp_sockaddr, .pr_recvoob = udp_recvoob, + .pr_send = udp_send, .pr_sendoob = udp_sendoob, .pr_generic = udp_usrreq, }; Index: src/sys/netinet6/raw_ip6.c diff -u src/sys/netinet6/raw_ip6.c:1.133 src/sys/netinet6/raw_ip6.c:1.134 --- src/sys/netinet6/raw_ip6.c:1.133 Tue Aug 5 05:24:27 2014 +++ src/sys/netinet6/raw_ip6.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip6.c,v 1.133 2014/08/05 05:24:27 rtr Exp $ */ +/* $NetBSD: raw_ip6.c,v 1.134 2014/08/05 07:55:32 rtr Exp $ */ /* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.133 2014/08/05 05:24:27 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.134 2014/08/05 07:55:32 rtr Exp $"); #include "opt_ipsec.h" @@ -838,6 +838,61 @@ rip6_recvoob(struct socket *so, struct m } static int +rip6_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct in6pcb *in6p = sotoin6pcb(so); + struct sockaddr_in6 tmp; + struct sockaddr_in6 *dst; + int error = 0; + + KASSERT(solocked(so)); + KASSERT(in6p != NULL); + KASSERT(m != NULL); + + /* + * Ship a packet out. The appropriate raw output + * routine handles any messaging necessary. + */ + + /* always copy sockaddr to avoid overwrites */ + if (so->so_state & SS_ISCONNECTED) { + if (nam) { + error = EISCONN; + goto release; + } + /* XXX */ + sockaddr_in6_init(&tmp, &in6p->in6p_faddr, 0, 0, 0); + dst = &tmp; + } else { + if (nam == NULL) { + error = ENOTCONN; + goto release; + } + if (nam->m_len != sizeof(tmp)) { + error = EINVAL; + goto release; + } + + tmp = *mtod(nam, struct sockaddr_in6 *); + dst = &tmp; + + if (dst->sin6_family != AF_INET6) { + error = EAFNOSUPPORT; + goto release; + } + } + error = rip6_output(m, so, dst, control); + m = NULL; + +release: + if (m) + m_freem(m); + + return error; +} + +static int rip6_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -852,7 +907,6 @@ int rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct lwp *l) { - struct in6pcb *in6p = sotoin6pcb(so); int error = 0; KASSERT(req != PRU_ACCEPT); @@ -867,6 +921,7 @@ rip6_usrreq(struct socket *so, int req, KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); if (req == PRU_PURGEIF) { @@ -884,47 +939,6 @@ rip6_usrreq(struct socket *so, int req, break; /* - * Ship a packet out. The appropriate raw output - * routine handles any messaging necessary. - */ - case PRU_SEND: - { - struct sockaddr_in6 tmp; - struct sockaddr_in6 *dst; - - /* always copy sockaddr to avoid overwrites */ - if (so->so_state & SS_ISCONNECTED) { - if (nam) { - error = EISCONN; - break; - } - /* XXX */ - sockaddr_in6_init(&tmp, &in6p->in6p_faddr, 0, 0, 0); - dst = &tmp; - } else { - if (nam == NULL) { - error = ENOTCONN; - break; - } - if (nam->m_len != sizeof(tmp)) { - error = EINVAL; - break; - } - - tmp = *mtod(nam, struct sockaddr_in6 *); - dst = &tmp; - - if (dst->sin6_family != AF_INET6) { - error = EAFNOSUPPORT; - break; - } - } - error = rip6_output(m, so, dst, control); - m = NULL; - break; - } - - /* * Not supported. */ case PRU_RCVD: @@ -993,6 +1007,7 @@ PR_WRAP_USRREQS(rip6) #define rip6_peeraddr rip6_peeraddr_wrapper #define rip6_sockaddr rip6_sockaddr_wrapper #define rip6_recvoob rip6_recvoob_wrapper +#define rip6_send rip6_send_wrapper #define rip6_sendoob rip6_sendoob_wrapper #define rip6_usrreq rip6_usrreq_wrapper @@ -1011,6 +1026,7 @@ const struct pr_usrreqs rip6_usrreqs = { .pr_peeraddr = rip6_peeraddr, .pr_sockaddr = rip6_sockaddr, .pr_recvoob = rip6_recvoob, + .pr_send = rip6_send, .pr_sendoob = rip6_sendoob, .pr_generic = rip6_usrreq, }; Index: src/sys/netinet6/udp6_usrreq.c diff -u src/sys/netinet6/udp6_usrreq.c:1.112 src/sys/netinet6/udp6_usrreq.c:1.113 --- src/sys/netinet6/udp6_usrreq.c:1.112 Tue Aug 5 05:24:27 2014 +++ src/sys/netinet6/udp6_usrreq.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: udp6_usrreq.c,v 1.112 2014/08/05 05:24:27 rtr Exp $ */ +/* $NetBSD: udp6_usrreq.c,v 1.113 2014/08/05 07:55:32 rtr Exp $ */ /* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.112 2014/08/05 05:24:27 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.113 2014/08/05 07:55:32 rtr Exp $"); #include "opt_inet.h" #include "opt_inet_csum.h" @@ -836,6 +836,25 @@ udp6_recvoob(struct socket *so, struct m } static int +udp6_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct in6pcb *in6p = sotoin6pcb(so); + int error = 0; + int s; + + KASSERT(solocked(so)); + KASSERT(in6p != NULL); + KASSERT(m != NULL); + + s = splsoftnet(); + error = udp6_output(in6p, m, nam, control, l); + splx(s); + + return error; +} + +static int udp6_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -853,7 +872,7 @@ udp6_usrreq(struct socket *so, int req, struct mbuf *control, struct lwp *l) { struct in6pcb *in6p = sotoin6pcb(so); - int s, error = 0; + int error = 0; KASSERT(req != PRU_ATTACH); KASSERT(req != PRU_DETACH); @@ -869,6 +888,7 @@ udp6_usrreq(struct socket *so, int req, KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); if (req == PRU_PURGEIF) { @@ -885,12 +905,6 @@ udp6_usrreq(struct socket *so, int req, } switch (req) { - case PRU_SEND: - s = splsoftnet(); - error = udp6_output(in6p, m, addr6, control, l); - splx(s); - return error; - case PRU_CONNECT2: case PRU_FASTTIMO: case PRU_SLOWTIMO: @@ -997,6 +1011,7 @@ PR_WRAP_USRREQS(udp6) #define udp6_peeraddr udp6_peeraddr_wrapper #define udp6_sockaddr udp6_sockaddr_wrapper #define udp6_recvoob udp6_recvoob_wrapper +#define udp6_send udp6_send_wrapper #define udp6_sendoob udp6_sendoob_wrapper #define udp6_usrreq udp6_usrreq_wrapper @@ -1015,6 +1030,7 @@ const struct pr_usrreqs udp6_usrreqs = { .pr_peeraddr = udp6_peeraddr, .pr_sockaddr = udp6_sockaddr, .pr_recvoob = udp6_recvoob, + .pr_send = udp6_send, .pr_sendoob = udp6_sendoob, .pr_generic = udp6_usrreq, }; Index: src/sys/netipsec/keysock.c diff -u src/sys/netipsec/keysock.c:1.40 src/sys/netipsec/keysock.c:1.41 --- src/sys/netipsec/keysock.c:1.40 Tue Aug 5 05:24:27 2014 +++ src/sys/netipsec/keysock.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: keysock.c,v 1.40 2014/08/05 05:24:27 rtr Exp $ */ +/* $NetBSD: keysock.c,v 1.41 2014/08/05 07:55:32 rtr Exp $ */ /* $FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */ /* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.40 2014/08/05 05:24:27 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.41 2014/08/05 07:55:32 rtr Exp $"); #include "opt_ipsec.h" @@ -617,6 +617,22 @@ key_recvoob(struct socket *so, struct mb } static int +key_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + int error = 0; + int s; + + KASSERT(solocked(so)); + + s = splsoftnet(); + error = raw_send(so, m, nam, control, l); + splx(s); + + return error; +} + +static int key_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -651,6 +667,7 @@ key_usrreq(struct socket *so, int req,st KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); s = splsoftnet(); @@ -682,6 +699,7 @@ PR_WRAP_USRREQS(key) #define key_peeraddr key_peeraddr_wrapper #define key_sockaddr key_sockaddr_wrapper #define key_recvoob key_recvoob_wrapper +#define key_send key_send_wrapper #define key_sendoob key_sendoob_wrapper #define key_usrreq key_usrreq_wrapper @@ -700,6 +718,7 @@ const struct pr_usrreqs key_usrreqs = { .pr_peeraddr = key_peeraddr, .pr_sockaddr = key_sockaddr, .pr_recvoob = key_recvoob, + .pr_send = key_send, .pr_sendoob = key_sendoob, .pr_generic = key_usrreq, }; Index: src/sys/netmpls/mpls_proto.c diff -u src/sys/netmpls/mpls_proto.c:1.21 src/sys/netmpls/mpls_proto.c:1.22 --- src/sys/netmpls/mpls_proto.c:1.21 Tue Aug 5 05:24:27 2014 +++ src/sys/netmpls/mpls_proto.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: mpls_proto.c,v 1.21 2014/08/05 05:24:27 rtr Exp $ */ +/* $NetBSD: mpls_proto.c,v 1.22 2014/08/05 07:55:32 rtr Exp $ */ /* * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.21 2014/08/05 05:24:27 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.22 2014/08/05 07:55:32 rtr Exp $"); #include "opt_inet.h" #include "opt_mbuftrace.h" @@ -189,6 +189,15 @@ mpls_recvoob(struct socket *so, struct m } static int +mpls_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + KASSERT(solocked(so)); + + return EOPNOTSUPP; +} + +static int mpls_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -215,6 +224,7 @@ mpls_usrreq(struct socket *so, int req, KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); return EOPNOTSUPP; @@ -316,6 +326,7 @@ PR_WRAP_USRREQS(mpls) #define mpls_peeraddr mpls_peeraddr_wrapper #define mpls_sockaddr mpls_sockaddr_wrapper #define mpls_recvoob mpls_recvoob_wrapper +#define mpls_send mpls_send_wrapper #define mpls_sendoob mpls_sendoob_wrapper #define mpls_usrreq mpls_usrreq_wrapper @@ -334,6 +345,7 @@ static const struct pr_usrreqs mpls_usrr .pr_peeraddr = mpls_peeraddr, .pr_sockaddr = mpls_sockaddr, .pr_recvoob = mpls_recvoob, + .pr_send = mpls_send, .pr_sendoob = mpls_sendoob, .pr_generic = mpls_usrreq, }; Index: src/sys/netnatm/natm.c diff -u src/sys/netnatm/natm.c:1.42 src/sys/netnatm/natm.c:1.43 --- src/sys/netnatm/natm.c:1.42 Tue Aug 5 05:24:27 2014 +++ src/sys/netnatm/natm.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: natm.c,v 1.42 2014/08/05 05:24:27 rtr Exp $ */ +/* $NetBSD: natm.c,v 1.43 2014/08/05 07:55:32 rtr Exp $ */ /* * Copyright (c) 1996 Charles D. Cranor and Washington University. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.42 2014/08/05 05:24:27 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.43 2014/08/05 07:55:32 rtr Exp $"); #include <sys/param.h> #include <sys/kmem.h> @@ -327,6 +327,42 @@ natm_recvoob(struct socket *so, struct m } static int +natm_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct natmpcb *npcb = (struct natmpcb *) so->so_pcb; + struct atm_pseudohdr *aph; + + KASSERT(solocked(so)); + KASSERT(pcb != NULL); + KASSERT(m != NULL); + + if (control && control->m_len) { + m_freem(control); + m_freem(m); + return EINVAL; + } + + /* + * send the data. we must put an atm_pseudohdr on first + */ + s = SPLSOFTNET(); + M_PREPEND(m, sizeof(*aph), M_WAITOK); + if (m == NULL) { + error = ENOBUFS; + break; + } + aph = mtod(m, struct atm_pseudohdr *); + ATM_PH_VPI(aph) = npcb->npcb_vpi; + ATM_PH_SETVCI(aph, npcb->npcb_vci); + ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0; + error = atm_output(npcb->npcb_ifp, m, NULL, NULL); + splx(s); + + return error; +} + +static int natm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -364,6 +400,7 @@ natm_usrreq(struct socket *so, int req, KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); s = SPLSOFTNET(); @@ -376,32 +413,6 @@ natm_usrreq(struct socket *so, int req, } switch (req) { - case PRU_SEND: /* send this data */ - if (control && control->m_len) { - m_freem(control); - m_freem(m); - error = EINVAL; - break; - } - - /* - * send the data. we must put an atm_pseudohdr on first - */ - - M_PREPEND(m, sizeof(*aph), M_WAITOK); - if (m == NULL) { - error = ENOBUFS; - break; - } - aph = mtod(m, struct atm_pseudohdr *); - ATM_PH_VPI(aph) = npcb->npcb_vpi; - ATM_PH_SETVCI(aph, npcb->npcb_vci); - ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0; - - error = atm_output(npcb->npcb_ifp, m, NULL, NULL); - - break; - case PRU_CONNECT2: /* connect two sockets */ case PRU_RCVD: /* have taken data; more room now */ case PRU_FASTTIMO: /* 200ms timeout */ @@ -515,6 +526,7 @@ PR_WRAP_USRREQS(natm) #define natm_peeraddr natm_peeraddr_wrapper #define natm_sockaddr natm_sockaddr_wrapper #define natm_recvoob natm_recvoob_wrapper +#define natm_send natm_send_wrapper #define natm_sendoob natm_sendoob_wrapper #define natm_usrreq natm_usrreq_wrapper @@ -533,6 +545,7 @@ const struct pr_usrreqs natm_usrreqs = { .pr_peeraddr = natm_peeraddr, .pr_sockaddr = natm_sockaddr, .pr_recvoob = natm_recvoob, + .pr_send = natm_send, .pr_sendoob = natm_sendoob, .pr_generic = natm_usrreq, }; Index: src/sys/nfs/nfs_socket.c diff -u src/sys/nfs/nfs_socket.c:1.191 src/sys/nfs/nfs_socket.c:1.192 --- src/sys/nfs/nfs_socket.c:1.191 Sun May 18 14:46:16 2014 +++ src/sys/nfs/nfs_socket.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_socket.c,v 1.191 2014/05/18 14:46:16 rmind Exp $ */ +/* $NetBSD: nfs_socket.c,v 1.192 2014/08/05 07:55:32 rtr Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1995 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.191 2014/05/18 14:46:16 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.192 2014/08/05 07:55:32 rtr Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -805,11 +805,11 @@ nfs_timer(void *arg) nmp->nm_sent < nmp->nm_cwnd) && (m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))){ if (so->so_state & SS_ISCONNECTED) - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_SEND, m, NULL, NULL, NULL); + error = (*so->so_proto->pr_usrreqs->pr_send)(so, + m, NULL, NULL, NULL); else - error = (*so->so_proto->pr_usrreqs->pr_generic)(so, - PRU_SEND, m, nmp->nm_nam, NULL, NULL); + error = (*so->so_proto->pr_usrreqs->pr_send)(so, + m, nmp->nm_nam, NULL, NULL); if (error) { if (NFSIGNORE_SOERROR(nmp->nm_soflags, error)) { #ifdef DEBUG Index: src/sys/rump/net/lib/libsockin/sockin.c diff -u src/sys/rump/net/lib/libsockin/sockin.c:1.55 src/sys/rump/net/lib/libsockin/sockin.c:1.56 --- src/sys/rump/net/lib/libsockin/sockin.c:1.55 Tue Aug 5 05:24:27 2014 +++ src/sys/rump/net/lib/libsockin/sockin.c Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sockin.c,v 1.55 2014/08/05 05:24:27 rtr Exp $ */ +/* $NetBSD: sockin.c,v 1.56 2014/08/05 07:55:32 rtr Exp $ */ /* * Copyright (c) 2008, 2009 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sockin.c,v 1.55 2014/08/05 05:24:27 rtr Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sockin.c,v 1.56 2014/08/05 07:55:32 rtr Exp $"); #include <sys/param.h> #include <sys/condvar.h> @@ -80,6 +80,8 @@ static int sockin_stat(struct socket *, static int sockin_peeraddr(struct socket *, struct mbuf *); static int sockin_sockaddr(struct socket *, struct mbuf *); static int sockin_recvoob(struct socket *, struct mbuf *, int); +static int sockin_send(struct socket *, struct mbuf *, struct mbuf *, + struct mbuf *, struct lwp *); static int sockin_sendoob(struct socket *, struct mbuf *, struct mbuf *); static int sockin_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *); @@ -100,6 +102,7 @@ static const struct pr_usrreqs sockin_us .pr_peeraddr = sockin_peeraddr, .pr_sockaddr = sockin_sockaddr, .pr_recvoob = sockin_recvoob, + .pr_send = sockin_send, .pr_sendoob = sockin_sendoob, .pr_generic = sockin_usrreq, }; @@ -597,6 +600,66 @@ sockin_recvoob(struct socket *so, struct } static int +sockin_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) +{ + struct sockaddr *saddr; + struct msghdr mhdr; + size_t iov_max, i; + struct iovec iov_buf[32], *iov; + struct mbuf *m2; + size_t tot, n; + int error = 0; + int s; + + bpf_mtap_af(&sockin_if, AF_UNSPEC, m); + + memset(&mhdr, 0, sizeof(mhdr)); + + iov_max = 0; + for (m2 = m; m2 != NULL; m2 = m2->m_next) { + iov_max++; + } + + if (iov_max <= __arraycount(iov_buf)) { + iov = iov_buf; + } else { + iov = kmem_alloc(sizeof(struct iovec) * iov_max, + KM_SLEEP); + } + + tot = 0; + for (i = 0, m2 = m; m2 != NULL; m2 = m2->m_next, i++) { + iov[i].iov_base = m2->m_data; + iov[i].iov_len = m2->m_len; + tot += m2->m_len; + } + mhdr.msg_iov = iov; + mhdr.msg_iovlen = i; + s = SO2S(so); + + if (nam != NULL) { + saddr = mtod(nam, struct sockaddr *); + mhdr.msg_name = saddr; + mhdr.msg_namelen = saddr->sa_len; + } + + rumpcomp_sockin_sendmsg(s, &mhdr, 0, &n); + + if (iov != iov_buf) + kmem_free(iov, sizeof(struct iovec) * iov_max); + + m_freem(m); + m_freem(control); + + /* this assumes too many things to list.. buthey, testing */ + if (!rump_threads) + sockin_process(so); + + return error; +} + +static int sockin_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) { KASSERT(solocked(so)); @@ -622,65 +685,10 @@ sockin_usrreq(struct socket *so, int req KASSERT(req != PRU_PEERADDR); KASSERT(req != PRU_SOCKADDR); KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); KASSERT(req != PRU_SENDOOB); switch (req) { - case PRU_SEND: - { - struct sockaddr *saddr; - struct msghdr mhdr; - size_t iov_max, i; - struct iovec iov_buf[32], *iov; - struct mbuf *m2; - size_t tot, n; - int s; - - bpf_mtap_af(&sockin_if, AF_UNSPEC, m); - - memset(&mhdr, 0, sizeof(mhdr)); - - iov_max = 0; - for (m2 = m; m2 != NULL; m2 = m2->m_next) { - iov_max++; - } - - if (iov_max <= __arraycount(iov_buf)) { - iov = iov_buf; - } else { - iov = kmem_alloc(sizeof(struct iovec) * iov_max, - KM_SLEEP); - } - - tot = 0; - for (i = 0, m2 = m; m2 != NULL; m2 = m2->m_next, i++) { - iov[i].iov_base = m2->m_data; - iov[i].iov_len = m2->m_len; - tot += m2->m_len; - } - mhdr.msg_iov = iov; - mhdr.msg_iovlen = i; - s = SO2S(so); - - if (nam != NULL) { - saddr = mtod(nam, struct sockaddr *); - mhdr.msg_name = saddr; - mhdr.msg_namelen = saddr->sa_len; - } - - rumpcomp_sockin_sendmsg(s, &mhdr, 0, &n); - - if (iov != iov_buf) - kmem_free(iov, sizeof(struct iovec) * iov_max); - - m_freem(m); - m_freem(control); - - /* this assumes too many things to list.. buthey, testing */ - if (!rump_threads) - sockin_process(so); - } - break; - default: panic("sockin_usrreq: IMPLEMENT ME, req %d not supported", req); } Index: src/sys/sys/protosw.h diff -u src/sys/sys/protosw.h:1.57 src/sys/sys/protosw.h:1.58 --- src/sys/sys/protosw.h:1.57 Tue Aug 5 05:24:27 2014 +++ src/sys/sys/protosw.h Tue Aug 5 07:55:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: protosw.h,v 1.57 2014/08/05 05:24:27 rtr Exp $ */ +/* $NetBSD: protosw.h,v 1.58 2014/08/05 07:55:32 rtr Exp $ */ /*- * Copyright (c) 1982, 1986, 1993 @@ -250,6 +250,8 @@ struct pr_usrreqs { int (*pr_peeraddr)(struct socket *, struct mbuf *); int (*pr_sockaddr)(struct socket *, struct mbuf *); int (*pr_recvoob)(struct socket *, struct mbuf *, int); + int (*pr_send)(struct socket *, struct mbuf *, struct mbuf *, + struct mbuf *, struct lwp *); int (*pr_sendoob)(struct socket *, struct mbuf *, struct mbuf *); int (*pr_generic)(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *); @@ -415,6 +417,16 @@ name##_recvoob_wrapper(struct socket *a, return rv; \ } \ static int \ +name##_send_wrapper(struct socket *a, struct mbuf *b, \ + struct mbuf *c, struct mbuf *d, struct lwp *e) \ +{ \ + int rv; \ + KERNEL_LOCK(1, NULL); \ + rv = name##_send(a, b, c, d, e); \ + KERNEL_UNLOCK_ONE(NULL); \ + return rv; \ +} \ +static int \ name##_sendoob_wrapper(struct socket *a, \ struct mbuf *b, struct mbuf *c) \ { \