summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVitaliy Makkoveev <mvs@cvs.openbsd.org>2022-08-27 20:28:02 +0000
committerVitaliy Makkoveev <mvs@cvs.openbsd.org>2022-08-27 20:28:02 +0000
commitcc56cf1e37947acee4384e248999b963238d3c9a (patch)
treee91fa35fe93da5b30a9a13f96a1394ea94973e64 /sys
parent85540f4cb5ed157c05c8a2d1e66aa31940d3b0d0 (diff)
Move PRU_SEND request to (*pru_send)().
The former PRU_SEND error path of gre_usrreq() had `control' mbuf(9) leak. It was fixed in new gre_send(). The former pfkeyv2_send() was renamed to pfkeyv2_dosend(). ok bluhm@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_usrreq.c208
-rw-r--r--sys/net/pfkeyv2.c45
-rw-r--r--sys/net/pfkeyv2.h4
-rw-r--r--sys/net/rtsock.c41
-rw-r--r--sys/netinet/ip_divert.c16
-rw-r--r--sys/netinet/ip_divert.h4
-rw-r--r--sys/netinet/ip_gre.c19
-rw-r--r--sys/netinet/ip_gre.h7
-rw-r--r--sys/netinet/ip_var.h4
-rw-r--r--sys/netinet/raw_ip.c87
-rw-r--r--sys/netinet/tcp_usrreq.c48
-rw-r--r--sys/netinet/tcp_var.h4
-rw-r--r--sys/netinet/udp_usrreq.c93
-rw-r--r--sys/netinet/udp_var.h4
-rw-r--r--sys/netinet6/ip6_divert.c16
-rw-r--r--sys/netinet6/ip6_divert.h4
-rw-r--r--sys/netinet6/ip6_var.h4
-rw-r--r--sys/netinet6/raw_ip6.c87
-rw-r--r--sys/sys/protosw.h7
-rw-r--r--sys/sys/unpcb.h4
20 files changed, 438 insertions, 268 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index fcbb08be5dc..2dbbabf689f 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_usrreq.c,v 1.175 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.176 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
@@ -137,6 +137,7 @@ const struct pr_usrreqs uipc_usrreqs = {
.pru_disconnect = uipc_disconnect,
.pru_shutdown = uipc_shutdown,
.pru_rcvd = uipc_rcvd,
+ .pru_send = uipc_send,
};
void
@@ -244,102 +245,6 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
}
break;
- case PRU_SEND:
- if (control) {
- sounlock(so);
- error = unp_internalize(control, p);
- solock(so);
- if (error)
- break;
- }
- switch (so->so_type) {
-
- case SOCK_DGRAM: {
- const struct sockaddr *from;
-
- if (nam) {
- if (unp->unp_conn) {
- error = EISCONN;
- break;
- }
- error = unp_connect(so, nam, p);
- if (error)
- break;
- }
-
- if ((so2 = unp_solock_peer(so)) == NULL) {
- if (nam != NULL)
- error = ECONNREFUSED;
- else
- error = ENOTCONN;
- break;
- }
-
- if (unp->unp_addr)
- from = mtod(unp->unp_addr, struct sockaddr *);
- else
- from = &sun_noname;
- if (sbappendaddr(so2, &so2->so_rcv, from, m, control)) {
- sorwakeup(so2);
- m = NULL;
- control = NULL;
- } else
- error = ENOBUFS;
-
- if (so2 != so)
- sounlock(so2);
-
- if (nam)
- unp_disconnect(unp);
- break;
- }
-
- case SOCK_STREAM:
- case SOCK_SEQPACKET:
- if (so->so_state & SS_CANTSENDMORE) {
- error = EPIPE;
- break;
- }
- if ((so2 = unp_solock_peer(so)) == NULL) {
- error = ENOTCONN;
- break;
- }
-
- /*
- * Send to paired receive port, and then raise
- * send buffer counts to maintain backpressure.
- * Wake up readers.
- */
- if (control) {
- if (sbappendcontrol(so2, &so2->so_rcv, m,
- control)) {
- control = NULL;
- } else {
- sounlock(so2);
- error = ENOBUFS;
- break;
- }
- } else if (so->so_type == SOCK_SEQPACKET)
- sbappendrecord(so2, &so2->so_rcv, m);
- else
- sbappend(so2, &so2->so_rcv, m);
- so->so_snd.sb_mbcnt = so2->so_rcv.sb_mbcnt;
- so->so_snd.sb_cc = so2->so_rcv.sb_cc;
- if (so2->so_rcv.sb_cc > 0)
- sorwakeup(so2);
-
- sounlock(so2);
- m = NULL;
- break;
-
- default:
- panic("uipc 4");
- }
- /* we need to undo unp_internalize in case of errors */
- if (control && error)
- unp_dispose(control);
- break;
-
case PRU_ABORT:
unp_detach(unp);
sofree(so, 0);
@@ -577,6 +482,115 @@ uipc_rcvd(struct socket *so)
}
int
+uipc_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ struct unpcb *unp = sotounpcb(so);
+ struct socket *so2;
+ int error;
+
+ if (control) {
+ sounlock(so);
+ error = unp_internalize(control, curproc);
+ solock(so);
+ if (error)
+ goto out;
+ }
+
+ switch (so->so_type) {
+ case SOCK_DGRAM: {
+ const struct sockaddr *from;
+
+ if (nam) {
+ if (unp->unp_conn) {
+ error = EISCONN;
+ break;
+ }
+ error = unp_connect(so, nam, curproc);
+ if (error)
+ break;
+ }
+
+ if ((so2 = unp_solock_peer(so)) == NULL) {
+ if (nam != NULL)
+ error = ECONNREFUSED;
+ else
+ error = ENOTCONN;
+ break;
+ }
+
+ if (unp->unp_addr)
+ from = mtod(unp->unp_addr, struct sockaddr *);
+ else
+ from = &sun_noname;
+ if (sbappendaddr(so2, &so2->so_rcv, from, m, control)) {
+ sorwakeup(so2);
+ m = NULL;
+ control = NULL;
+ } else
+ error = ENOBUFS;
+
+ if (so2 != so)
+ sounlock(so2);
+
+ if (nam)
+ unp_disconnect(unp);
+ break;
+ }
+
+ case SOCK_STREAM:
+ case SOCK_SEQPACKET:
+ if (so->so_state & SS_CANTSENDMORE) {
+ error = EPIPE;
+ break;
+ }
+ if ((so2 = unp_solock_peer(so)) == NULL) {
+ error = ENOTCONN;
+ break;
+ }
+
+ /*
+ * Send to paired receive port, and then raise
+ * send buffer counts to maintain backpressure.
+ * Wake up readers.
+ */
+ if (control) {
+ if (sbappendcontrol(so2, &so2->so_rcv, m, control)) {
+ control = NULL;
+ } else {
+ sounlock(so2);
+ error = ENOBUFS;
+ break;
+ }
+ } else if (so->so_type == SOCK_SEQPACKET)
+ sbappendrecord(so2, &so2->so_rcv, m);
+ else
+ sbappend(so2, &so2->so_rcv, m);
+ so->so_snd.sb_mbcnt = so2->so_rcv.sb_mbcnt;
+ so->so_snd.sb_cc = so2->so_rcv.sb_cc;
+ if (so2->so_rcv.sb_cc > 0)
+ sorwakeup(so2);
+
+ sounlock(so2);
+ m = NULL;
+ break;
+
+ default:
+ panic("uipc 4");
+ }
+
+ /* we need to undo unp_internalize in case of errors */
+ if (control && error)
+ unp_dispose(control);
+
+out:
+ m_freem(control);
+ m_freem(m);
+
+ return (error);
+}
+
+int
uipc_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
size_t newlen)
{
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index 6347579f317..995fb51036f 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.242 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.243 2022/08/27 20:28:01 mvs Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -173,6 +173,8 @@ int pfkeyv2_attach(struct socket *, int);
int pfkeyv2_detach(struct socket *);
int pfkeyv2_disconnect(struct socket *);
int pfkeyv2_shutdown(struct socket *);
+int pfkeyv2_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
int pfkeyv2_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
struct mbuf *, struct proc *);
int pfkeyv2_output(struct mbuf *, struct socket *, struct sockaddr *,
@@ -207,6 +209,7 @@ const struct pr_usrreqs pfkeyv2_usrreqs = {
.pru_detach = pfkeyv2_detach,
.pru_disconnect = pfkeyv2_disconnect,
.pru_shutdown = pfkeyv2_shutdown,
+ .pru_send = pfkeyv2_send,
};
const struct protosw pfkeysw[] = {
@@ -351,6 +354,34 @@ pfkeyv2_shutdown(struct socket *so)
}
int
+pfkeyv2_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ int error;
+
+ soassertlocked(so);
+
+ if (control && control->m_len) {
+ error = EOPNOTSUPP;
+ goto out;
+ }
+
+ if (nam) {
+ error = EISCONN;
+ goto out;
+ }
+
+ error = (*so->so_proto->pr_output)(m, so, NULL, NULL);
+ m = NULL;
+
+out:
+ m_freem(control);
+ m_freem(m);
+
+ return (error);
+}
+
+int
pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m,
struct mbuf *nam, struct mbuf *control, struct proc *p)
{
@@ -399,14 +430,6 @@ pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m,
case PRU_SENDOOB:
error = EOPNOTSUPP;
break;
- case PRU_SEND:
- if (nam) {
- error = EISCONN;
- break;
- }
- error = (*so->so_proto->pr_output)(m, so, NULL, NULL);
- m = NULL;
- break;
default:
panic("pfkeyv2_usrreq");
}
@@ -452,7 +475,7 @@ pfkeyv2_output(struct mbuf *mbuf, struct socket *so,
*/
sounlock(so);
- error = pfkeyv2_send(so, message, mbuf->m_pkthdr.len);
+ error = pfkeyv2_dosend(so, message, mbuf->m_pkthdr.len);
solock(so);
ret:
@@ -1134,7 +1157,7 @@ pfkeyv2_get_proto_alg(u_int8_t satype, u_int8_t *sproto, int *alg)
* Handle all messages from userland to kernel.
*/
int
-pfkeyv2_send(struct socket *so, void *message, int len)
+pfkeyv2_dosend(struct socket *so, void *message, int len)
{
int i, j, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST;
int delflag = 0;
diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h
index 2e2c64880fb..db0a7cd1433 100644
--- a/sys/net/pfkeyv2.h
+++ b/sys/net/pfkeyv2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.h,v 1.92 2022/03/02 09:27:34 claudio Exp $ */
+/* $OpenBSD: pfkeyv2.h,v 1.93 2022/08/27 20:28:01 mvs Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) January 1998
*
@@ -412,7 +412,7 @@ int pfkeyv2_acquire(struct ipsec_policy *, union sockaddr_union *,
int pfkeyv2_get(struct tdb *, void **, void **, int *, int *);
int pfkeyv2_policy(struct ipsec_acquire *, void **, void **, int *);
-int pfkeyv2_send(struct socket *, void *, int);
+int pfkeyv2_dosend(struct socket *, void *, int);
int pfkeyv2_sendmessage(void **, int, struct socket *, u_int8_t, int, u_int);
int pfkeyv2_dump_policy(struct ipsec_policy *, void **, void **, int *);
int pfkeyv2_dump_walker(struct tdb *, void *, int);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 08e05a7902e..19c77bd8538 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.342 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: rtsock.c,v 1.343 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -117,6 +117,8 @@ int route_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
int route_disconnect(struct socket *);
int route_shutdown(struct socket *);
int route_rcvd(struct socket *);
+int route_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
void route_input(struct mbuf *m0, struct socket *, sa_family_t);
int route_arp_conflict(struct rtentry *, struct rt_addrinfo *);
int route_cleargateway(struct rtentry *, void *, unsigned int);
@@ -260,14 +262,6 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
case PRU_SENDOOB:
error = EOPNOTSUPP;
break;
- case PRU_SEND:
- if (nam) {
- error = EISCONN;
- break;
- }
- error = (*so->so_proto->pr_output)(m, so, NULL, NULL);
- m = NULL;
- break;
default:
panic("route_usrreq");
}
@@ -384,6 +378,34 @@ route_rcvd(struct socket *so)
}
int
+route_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ int error;
+
+ soassertlocked(so);
+
+ if (control && control->m_len) {
+ error = EOPNOTSUPP;
+ goto out;
+ }
+
+ if (nam) {
+ error = EISCONN;
+ goto out;
+ }
+
+ error = (*so->so_proto->pr_output)(m, so, NULL, NULL);
+ m = NULL;
+
+out:
+ m_freem(control);
+ m_freem(m);
+
+ return (error);
+}
+
+int
route_ctloutput(int op, struct socket *so, int level, int optname,
struct mbuf *m)
{
@@ -2425,6 +2447,7 @@ const struct pr_usrreqs route_usrreqs = {
.pru_disconnect = route_disconnect,
.pru_shutdown = route_shutdown,
.pru_rcvd = route_rcvd,
+ .pru_send = route_send,
};
const struct protosw routesw[] = {
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index bb2b637fe83..11583387f61 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.77 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.78 2022/08/27 20:28:01 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -68,6 +68,7 @@ const struct pr_usrreqs divert_usrreqs = {
.pru_detach = divert_detach,
.pru_bind = divert_bind,
.pru_shutdown = divert_shutdown,
+ .pru_send = divert_send,
};
int divbhashsize = DIVERTHASHSIZE;
@@ -269,9 +270,6 @@ divert_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
}
switch (req) {
- case PRU_SEND:
- return (divert_output(inp, m, addr, control));
-
case PRU_ABORT:
soisdisconnected(so);
in_pcbdetach(inp);
@@ -364,6 +362,16 @@ divert_shutdown(struct socket *so)
}
int
+divert_send(struct socket *so, struct mbuf *m, struct mbuf *addr,
+ struct mbuf *control)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ soassertlocked(so);
+ return (divert_output(inp, m, addr, control));
+}
+
+int
divert_sysctl_divstat(void *oldp, size_t *oldlenp, void *newp)
{
uint64_t counters[divs_ncounters];
diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h
index c3009f6a16e..020f2ae2ef1 100644
--- a/sys/netinet/ip_divert.h
+++ b/sys/netinet/ip_divert.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.h,v 1.18 2022/08/22 21:18:48 mvs Exp $ */
+/* $OpenBSD: ip_divert.h,v 1.19 2022/08/27 20:28:01 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -76,5 +76,7 @@ int divert_attach(struct socket *, int);
int divert_detach(struct socket *);
int divert_bind(struct socket *, struct mbuf *, struct proc *);
int divert_shutdown(struct socket *);
+int divert_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
#endif /* _KERNEL */
#endif /* _IP_DIVERT_H_ */
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index 6ffa80a60cc..55a853f45f8 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.c,v 1.79 2022/08/22 21:18:48 mvs Exp $ */
+/* $OpenBSD: ip_gre.c,v 1.80 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: ip_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -69,16 +69,24 @@ const struct pr_usrreqs gre_usrreqs = {
.pru_connect = rip_connect,
.pru_disconnect = rip_disconnect,
.pru_shutdown = rip_shutdown,
+ .pru_send = gre_send,
};
int
gre_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
struct mbuf *control, struct proc *p)
{
+ return rip_usrreq(so, req, m, nam, control, p);
+}
+
+int
+gre_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
#ifdef PIPEX
struct inpcb *inp = sotoinpcb(so);
- if (inp != NULL && inp->inp_pipex && req == PRU_SEND) {
+ if (inp->inp_pipex) {
struct sockaddr_in *sin4;
struct in_addr *ina_dst;
@@ -103,10 +111,13 @@ gre_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
}
}
- if (m == NULL)
+ if (m == NULL) {
+ m_freem(control);
return (ENOMEM);
+ }
}
#endif
- return rip_usrreq(so, req, m, nam, control, p);
+ return rip_send(so, m, nam, control);
}
+
#endif /* if NGRE > 0 */
diff --git a/sys/netinet/ip_gre.h b/sys/netinet/ip_gre.h
index 7bef90b3b75..b626e3115bb 100644
--- a/sys/netinet/ip_gre.h
+++ b/sys/netinet/ip_gre.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.h,v 1.17 2022/08/15 09:11:39 mvs Exp $ */
+/* $OpenBSD: ip_gre.h,v 1.18 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: ip_gre.h,v 1.3 1998/10/07 23:33:02 thorpej Exp $ */
/*
@@ -56,6 +56,9 @@
extern const struct pr_usrreqs gre_usrreqs;
-int gre_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+int gre_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
+ struct mbuf *, struct proc *);
+int gre_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
#endif /* _KERNEL */
#endif /* _NETINET_IP_GRE_H_ */
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 6ad01c463c2..d96d55fa5b9 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_var.h,v 1.101 2022/08/22 21:18:48 mvs Exp $ */
+/* $OpenBSD: ip_var.h,v 1.102 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
@@ -264,6 +264,8 @@ int rip_bind(struct socket *so, struct mbuf *, struct proc *);
int rip_connect(struct socket *, struct mbuf *);
int rip_disconnect(struct socket *);
int rip_shutdown(struct socket *);
+int rip_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
#ifdef MROUTING
extern struct socket *ip_mrouter[]; /* multicast routing daemon */
#endif
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index f226a7af9f5..958c5dddbb2 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.138 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.139 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -111,6 +111,7 @@ const struct pr_usrreqs rip_usrreqs = {
.pru_connect = rip_connect,
.pru_disconnect = rip_disconnect,
.pru_shutdown = rip_shutdown,
+ .pru_send = rip_send,
};
/*
@@ -491,42 +492,6 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
error = EOPNOTSUPP;
break;
- /*
- * Ship a packet out. The appropriate raw output
- * routine handles any massaging necessary.
- */
- case PRU_SEND:
- {
- struct sockaddr_in dst;
-
- memset(&dst, 0, sizeof(dst));
- dst.sin_family = AF_INET;
- dst.sin_len = sizeof(dst);
- if (so->so_state & SS_ISCONNECTED) {
- if (nam) {
- error = EISCONN;
- break;
- }
- dst.sin_addr = inp->inp_faddr;
- } else {
- struct sockaddr_in *addr;
-
- if (nam == NULL) {
- error = ENOTCONN;
- break;
- }
- if ((error = in_nam2sin(nam, &addr)))
- break;
- dst.sin_addr = addr->sin_addr;
- }
-#ifdef IPSEC
- /* XXX Find an IPsec TDB */
-#endif
- error = rip_output(m, so, sintosa(&dst), NULL);
- m = NULL;
- break;
- }
-
case PRU_SENSE:
/*
* stat: don't bother with a blocksize.
@@ -672,3 +637,51 @@ rip_shutdown(struct socket *so)
return (0);
}
+
+int
+rip_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ struct inpcb *inp = sotoinpcb(so);
+ struct sockaddr_in dst;
+ int error;
+
+ soassertlocked(so);
+
+ /*
+ * Ship a packet out. The appropriate raw output
+ * routine handles any massaging necessary.
+ */
+ memset(&dst, 0, sizeof(dst));
+ dst.sin_family = AF_INET;
+ dst.sin_len = sizeof(dst);
+ if (so->so_state & SS_ISCONNECTED) {
+ if (nam) {
+ error = EISCONN;
+ goto out;
+ }
+ dst.sin_addr = inp->inp_faddr;
+ } else {
+ struct sockaddr_in *addr;
+
+ if (nam == NULL) {
+ error = ENOTCONN;
+ goto out;
+ }
+ if ((error = in_nam2sin(nam, &addr)))
+ goto out;
+ dst.sin_addr = addr->sin_addr;
+ }
+#ifdef IPSEC
+ /* XXX Find an IPsec TDB */
+#endif
+ error = rip_output(m, so, sintosa(&dst), NULL);
+ m = NULL;
+
+out:
+ m_freem(control);
+ m_freem(m);
+
+ return (error);
+}
+
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 7c473d51146..af327f2bd56 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.195 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.196 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -122,6 +122,7 @@ const struct pr_usrreqs tcp_usrreqs = {
.pru_disconnect = tcp_disconnect,
.pru_shutdown = tcp_shutdown,
.pru_rcvd = tcp_rcvd,
+ .pru_send = tcp_send,
};
static int pr_slowhz = PR_SLOWHZ;
@@ -226,15 +227,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
break;
/*
- * Do a send by putting data in output queue and updating urgent
- * marker if URG set. Possibly send more data.
- */
- case PRU_SEND:
- sbappendstream(so, &so->so_snd, m);
- error = tcp_output(tp);
- break;
-
- /*
* Abort the TCP.
*/
case PRU_ABORT:
@@ -935,6 +927,42 @@ tcp_rcvd(struct socket *so)
}
/*
+ * Do a send by putting data in output queue and updating urgent
+ * marker if URG set. Possibly send more data.
+ */
+int
+tcp_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ struct inpcb *inp;
+ struct tcpcb *tp;
+ int error;
+ short ostate;
+
+ soassertlocked(so);
+
+ if ((error = tcp_sogetpcb(so, &inp, &tp)))
+ goto out;
+
+ if (so->so_options & SO_DEBUG)
+ ostate = tp->t_state;
+
+ sbappendstream(so, &so->so_snd, m);
+ m = NULL;
+
+ error = tcp_output(tp);
+
+ if (so->so_options & SO_DEBUG)
+ tcp_trace(TA_USER, ostate, tp, tp, NULL, PRU_SEND, 0);
+
+out:
+ m_freem(control);
+ m_freem(m);
+
+ return (error);
+}
+
+/*
* Initiate (or continue) disconnect.
* If embryonic state, just send reset (once).
* If in ``let data drain'' option and linger null, just drop.
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 6b9a237ba90..b07457c8613 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.148 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.149 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -721,6 +721,8 @@ int tcp_accept(struct socket *, struct mbuf *);
int tcp_disconnect(struct socket *);
int tcp_shutdown(struct socket *);
int tcp_rcvd(struct socket *);
+int tcp_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
void tcp_xmit_timer(struct tcpcb *, int);
void tcpdropoldhalfopen(struct tcpcb *, u_int16_t);
void tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 75b507c0552..a85645ed9be 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.290 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.291 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -130,6 +130,7 @@ const struct pr_usrreqs udp_usrreqs = {
.pru_connect = udp_connect,
.pru_disconnect = udp_disconnect,
.pru_shutdown = udp_shutdown,
+ .pru_send = udp_send,
};
const struct sysctl_bounded_args udpctl_vars[] = {
@@ -1086,46 +1087,6 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
error = EOPNOTSUPP;
break;
- case PRU_SEND:
-#ifdef PIPEX
- if (inp->inp_pipex) {
- struct pipex_session *session;
-
- if (addr != NULL)
- session =
- pipex_l2tp_userland_lookup_session(m,
- mtod(addr, struct sockaddr *));
- else
-#ifdef INET6
- if (inp->inp_flags & INP_IPV6)
- session =
- pipex_l2tp_userland_lookup_session_ipv6(
- m, inp->inp_faddr6);
- else
-#endif
- session =
- pipex_l2tp_userland_lookup_session_ipv4(
- m, inp->inp_faddr);
- if (session != NULL) {
- m = pipex_l2tp_userland_output(m, session);
- pipex_rele_session(session);
-
- if (m == NULL) {
- error = ENOMEM;
- goto release;
- }
- }
- }
-#endif
-
-#ifdef INET6
- if (inp->inp_flags & INP_IPV6)
- error = udp6_output(inp, m, addr, control);
- else
-#endif
- error = udp_output(inp, m, addr, control);
- return (error);
-
case PRU_ABORT:
soisdisconnected(so);
in_pcbdetach(inp);
@@ -1293,6 +1254,56 @@ udp_shutdown(struct socket *so)
return (0);
}
+int
+udp_send(struct socket *so, struct mbuf *m, struct mbuf *addr,
+ struct mbuf *control)
+{
+ struct inpcb *inp = sotoinpcb(so);
+ int error;
+
+ soassertlocked(so);
+
+#ifdef PIPEX
+ if (inp->inp_pipex) {
+ struct pipex_session *session;
+
+ if (addr != NULL)
+ session =
+ pipex_l2tp_userland_lookup_session(m,
+ mtod(addr, struct sockaddr *));
+ else
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ session =
+ pipex_l2tp_userland_lookup_session_ipv6(
+ m, inp->inp_faddr6);
+ else
+#endif
+ session =
+ pipex_l2tp_userland_lookup_session_ipv4(
+ m, inp->inp_faddr);
+ if (session != NULL) {
+ m = pipex_l2tp_userland_output(m, session);
+ pipex_rele_session(session);
+
+ if (m == NULL) {
+ m_freem(control);
+ return (ENOMEM);
+ }
+ }
+ }
+#endif
+
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ error = udp6_output(inp, m, addr, control);
+ else
+#endif
+ error = udp_output(inp, m, addr, control);
+
+ return (error);
+}
+
/*
* Sysctl for udp variables.
*/
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 945695ba3c5..bdf2dff98b4 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_var.h,v 1.42 2022/08/22 21:18:48 mvs Exp $ */
+/* $OpenBSD: udp_var.h,v 1.43 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */
/*
@@ -147,5 +147,7 @@ int udp_bind(struct socket *, struct mbuf *, struct proc *);
int udp_connect(struct socket *, struct mbuf *);
int udp_disconnect(struct socket *);
int udp_shutdown(struct socket *);
+int udp_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
#endif /* _KERNEL */
#endif /* _NETINET_UDP_VAR_H_ */
diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c
index 2ecce90e31b..b9617bab118 100644
--- a/sys/netinet6/ip6_divert.c
+++ b/sys/netinet6/ip6_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_divert.c,v 1.76 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.77 2022/08/27 20:28:01 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -69,6 +69,7 @@ const struct pr_usrreqs divert6_usrreqs = {
.pru_detach = divert6_detach,
.pru_bind = divert6_bind,
.pru_shutdown = divert6_shutdown,
+ .pru_send = divert6_send,
};
int divb6hashsize = DIVERTHASHSIZE;
@@ -275,9 +276,6 @@ divert6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
}
switch (req) {
- case PRU_SEND:
- return (divert6_output(inp, m, addr, control));
-
case PRU_ABORT:
soisdisconnected(so);
in_pcbdetach(inp);
@@ -372,6 +370,16 @@ divert6_shutdown(struct socket *so)
}
int
+divert6_send(struct socket *so, struct mbuf *m, struct mbuf *addr,
+ struct mbuf *control)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ soassertlocked(so);
+ return (divert6_output(inp, m, addr, control));
+}
+
+int
divert6_sysctl_div6stat(void *oldp, size_t *oldlenp, void *newp)
{
uint64_t counters[div6s_ncounters];
diff --git a/sys/netinet6/ip6_divert.h b/sys/netinet6/ip6_divert.h
index 9bf1b6ab1ba..0414661edcf 100644
--- a/sys/netinet6/ip6_divert.h
+++ b/sys/netinet6/ip6_divert.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_divert.h,v 1.16 2022/08/22 21:18:48 mvs Exp $ */
+/* $OpenBSD: ip6_divert.h,v 1.17 2022/08/27 20:28:01 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -76,6 +76,8 @@ int divert6_attach(struct socket *, int);
int divert6_detach(struct socket *);
int divert6_bind(struct socket *, struct mbuf *, struct proc *);
int divert6_shutdown(struct socket *);
+int divert6_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
#endif /* _KERNEL */
#endif /* _IP6_DIVERT_H_ */
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 63ec50bfa04..e24406f826e 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_var.h,v 1.99 2022/08/22 21:18:48 mvs Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.100 2022/08/27 20:28:01 mvs Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@@ -359,6 +359,8 @@ int rip6_bind(struct socket *, struct mbuf *, struct proc *);
int rip6_connect(struct socket *, struct mbuf *);
int rip6_disconnect(struct socket *);
int rip6_shutdown(struct socket *);
+int rip6_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
int rip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int dest6_input(struct mbuf **, int *, int, int);
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 25715c8435e..c1270d73c8a 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip6.c,v 1.158 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.159 2022/08/27 20:28:01 mvs Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@@ -113,6 +113,7 @@ const struct pr_usrreqs rip6_usrreqs = {
.pru_connect = rip6_connect,
.pru_disconnect = rip6_disconnect,
.pru_shutdown = rip6_shutdown,
+ .pru_send = rip6_send,
};
/*
@@ -609,42 +610,6 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
error = EOPNOTSUPP;
break;
- /*
- * Ship a packet out. The appropriate raw output
- * routine handles any messaging necessary.
- */
- case PRU_SEND:
- {
- struct sockaddr_in6 dst;
-
- /* always copy sockaddr to avoid overwrites */
- memset(&dst, 0, sizeof(dst));
- dst.sin6_family = AF_INET6;
- dst.sin6_len = sizeof(dst);
- if (so->so_state & SS_ISCONNECTED) {
- if (nam) {
- error = EISCONN;
- break;
- }
- dst.sin6_addr = in6p->inp_faddr6;
- } else {
- struct sockaddr_in6 *addr6;
-
- if (nam == NULL) {
- error = ENOTCONN;
- break;
- }
- if ((error = in6_nam2sin6(nam, &addr6)))
- break;
- dst.sin6_addr = addr6->sin6_addr;
- dst.sin6_scope_id = addr6->sin6_scope_id;
- }
- error = rip6_output(m, so, sin6tosa(&dst), control);
- control = NULL;
- m = NULL;
- break;
- }
-
case PRU_SENSE:
/*
* stat: don't bother with a blocksize
@@ -807,6 +772,54 @@ rip6_shutdown(struct socket *so)
}
int
+rip6_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ struct inpcb *in6p = sotoinpcb(so);
+ struct sockaddr_in6 dst;
+ int error;
+
+ soassertlocked(so);
+
+ /*
+ * Ship a packet out. The appropriate raw output
+ * routine handles any messaging necessary.
+ */
+
+ /* always copy sockaddr to avoid overwrites */
+ memset(&dst, 0, sizeof(dst));
+ dst.sin6_family = AF_INET6;
+ dst.sin6_len = sizeof(dst);
+ if (so->so_state & SS_ISCONNECTED) {
+ if (nam) {
+ error = EISCONN;
+ goto out;
+ }
+ dst.sin6_addr = in6p->inp_faddr6;
+ } else {
+ struct sockaddr_in6 *addr6;
+
+ if (nam == NULL) {
+ error = ENOTCONN;
+ goto out;
+ }
+ if ((error = in6_nam2sin6(nam, &addr6)))
+ goto out;
+ dst.sin6_addr = addr6->sin6_addr;
+ dst.sin6_scope_id = addr6->sin6_scope_id;
+ }
+ error = rip6_output(m, so, sin6tosa(&dst), control);
+ control = NULL;
+ m = NULL;
+
+out:
+ m_freem(control);
+ m_freem(m);
+
+ return (error);
+}
+
+int
rip6_sysctl_rip6stat(void *oldp, size_t *oldplen, void *newp)
{
struct rip6stat rip6stat;
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index c7afdcada0d..cec2616288c 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: protosw.h,v 1.44 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: protosw.h,v 1.45 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $ */
/*-
@@ -73,6 +73,8 @@ struct pr_usrreqs {
int (*pru_disconnect)(struct socket *);
int (*pru_shutdown)(struct socket *);
int (*pru_rcvd)(struct socket *);
+ int (*pru_send)(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
};
struct protosw {
@@ -326,8 +328,7 @@ static inline int
pru_send(struct socket *so, struct mbuf *top, struct mbuf *addr,
struct mbuf *control)
{
- return (*so->so_proto->pr_usrreqs->pru_usrreq)(so,
- PRU_SEND, top, addr, control, curproc);
+ return (*so->so_proto->pr_usrreqs->pru_send)(so, top, addr, control);
}
static inline int
diff --git a/sys/sys/unpcb.h b/sys/sys/unpcb.h
index 9248fb9295d..4521ceb25ba 100644
--- a/sys/sys/unpcb.h
+++ b/sys/sys/unpcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: unpcb.h,v 1.34 2022/08/26 16:17:39 mvs Exp $ */
+/* $OpenBSD: unpcb.h,v 1.35 2022/08/27 20:28:01 mvs Exp $ */
/* $NetBSD: unpcb.h,v 1.6 1994/06/29 06:46:08 cgd Exp $ */
/*
@@ -120,6 +120,8 @@ int uipc_accept(struct socket *, struct mbuf *);
int uipc_disconnect(struct socket *);
int uipc_shutdown(struct socket *);
int uipc_rcvd(struct socket *);
+int uipc_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
void unp_init(void);
int unp_bind(struct unpcb *, struct mbuf *, struct proc *);