summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2022-05-05 16:44:23 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2022-05-05 16:44:23 +0000
commitb1fd359239a96f264a2caf0c5ba7bfa25d45419c (patch)
treee326eb6e87348cef1512a7ec3698341c89c9f758 /sys/netinet
parentbe8113c872aa20def6b9ecb7b5c50247ff278f4f (diff)
Clean up divert_packet(). Function does not return error, make it
void. Introduce mutex and refcounting for inp like in the other PCB functions. OK sashan@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_divert.c68
-rw-r--r--sys/netinet/ip_divert.h4
2 files changed, 38 insertions, 34 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 5b987fb7561..187bbe8c96c 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.66 2022/02/25 23:51:03 guenther Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.67 2022/05/05 16:44:22 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -171,30 +171,37 @@ fail:
return (error ? error : EINVAL);
}
-int
+void
divert_packet(struct mbuf *m, int dir, u_int16_t divert_port)
{
- struct inpcb *inp;
- struct socket *sa = NULL;
- struct sockaddr_in addr;
+ struct inpcb *inp = NULL;
+ struct socket *so;
+ struct sockaddr_in sin;
- inp = NULL;
divstat_inc(divs_ipackets);
if (m->m_len < sizeof(struct ip) &&
(m = m_pullup(m, sizeof(struct ip))) == NULL) {
divstat_inc(divs_errors);
- return (0);
+ goto bad;
}
+ mtx_enter(&divbtable.inpt_mtx);
TAILQ_FOREACH(inp, &divbtable.inpt_queue, inp_queue) {
- if (inp->inp_lport == divert_port)
- break;
+ if (inp->inp_lport != divert_port)
+ continue;
+ in_pcbref(inp);
+ break;
+ }
+ mtx_leave(&divbtable.inpt_mtx);
+ if (inp == NULL) {
+ divstat_inc(divs_noport);
+ goto bad;
}
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(sin);
if (dir == PF_IN) {
struct ifaddr *ifa;
@@ -202,37 +209,34 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port)
ifp = if_get(m->m_pkthdr.ph_ifidx);
if (ifp == NULL) {
- m_freem(m);
- return (0);
+ divstat_inc(divs_errors);
+ goto bad;
}
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
- addr.sin_addr.s_addr = satosin(
- ifa->ifa_addr)->sin_addr.s_addr;
+ sin.sin_addr = satosin(ifa->ifa_addr)->sin_addr;
break;
}
if_put(ifp);
}
- if (inp) {
- sa = inp->inp_socket;
- if (sbappendaddr(sa, &sa->so_rcv, sintosa(&addr), m, NULL) == 0) {
- divstat_inc(divs_fullsock);
- m_freem(m);
- return (0);
- } else {
- KERNEL_LOCK();
- sorwakeup(inp->inp_socket);
- KERNEL_UNLOCK();
- }
+ so = inp->inp_socket;
+ if (sbappendaddr(so, &so->so_rcv, sintosa(&sin), m, NULL) == 0) {
+ divstat_inc(divs_fullsock);
+ goto bad;
}
+ KERNEL_LOCK();
+ sorwakeup(inp->inp_socket);
+ KERNEL_UNLOCK();
- if (sa == NULL) {
- divstat_inc(divs_noport);
- m_freem(m);
- }
- return (0);
+ in_pcbunref(inp);
+ return;
+
+ bad:
+ if (inp != NULL)
+ in_pcbunref(inp);
+ m_freem(m);
}
/*ARGSUSED*/
diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h
index 11780b57956..c9021274e96 100644
--- a/sys/netinet/ip_divert.h
+++ b/sys/netinet/ip_divert.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.h,v 1.14 2022/02/25 23:51:03 guenther Exp $ */
+/* $OpenBSD: ip_divert.h,v 1.15 2022/05/05 16:44:22 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -66,7 +66,7 @@ divstat_inc(enum divstat_counters c)
extern struct inpcbtable divbtable;
void divert_init(void);
-int divert_packet(struct mbuf *, int, u_int16_t);
+void divert_packet(struct mbuf *, int, u_int16_t);
int divert_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int divert_usrreq(struct socket *,
int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);