From: bluhm Date: Thu, 5 May 2022 16:44:22 +0000 (+0000) Subject: Clean up divert_packet(). Function does not return error, make it X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=37b541b9fa24c6abff9c48e6d61b07889687c1a8;p=openbsd 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@ --- diff --git a/sys/net/pf.c b/sys/net/pf.c index e774a8bd141..6872d1a2381 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.1128 2022/05/03 13:32:47 sashan Exp $ */ +/* $OpenBSD: pf.c,v 1.1129 2022/05/05 16:44:22 bluhm Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -7403,13 +7403,13 @@ done: case PF_DIVERT: switch (pd.af) { case AF_INET: - if (!divert_packet(pd.m, pd.dir, r->divert.port)) - pd.m = NULL; + divert_packet(pd.m, pd.dir, r->divert.port); + pd.m = NULL; break; #ifdef INET6 case AF_INET6: - if (!divert6_packet(pd.m, pd.dir, r->divert.port)) - pd.m = NULL; + divert6_packet(pd.m, pd.dir, r->divert.port); + pd.m = NULL; break; #endif /* INET6 */ } 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 @@ -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 @@ -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 *); diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c index 083e0938fb3..35eb40945c1 100644 --- a/sys/netinet6/ip6_divert.c +++ b/sys/netinet6/ip6_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_divert.c,v 1.65 2022/02/25 23:51:04 guenther Exp $ */ +/* $OpenBSD: ip6_divert.c,v 1.66 2022/05/05 16:44:22 bluhm Exp $ */ /* * Copyright (c) 2009 Michele Marchetto @@ -177,30 +177,37 @@ fail: return (error ? error : EINVAL); } -int +void divert6_packet(struct mbuf *m, int dir, u_int16_t divert_port) { - struct inpcb *inp; - struct socket *sa = NULL; - struct sockaddr_in6 addr; + struct inpcb *inp = NULL; + struct socket *so; + struct sockaddr_in6 sin6; - inp = NULL; div6stat_inc(div6s_ipackets); if (m->m_len < sizeof(struct ip6_hdr) && (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { div6stat_inc(div6s_errors); - return (0); + goto bad; } + mtx_enter(&divb6table.inpt_mtx); TAILQ_FOREACH(inp, &divb6table.inpt_queue, inp_queue) { - if (inp->inp_lport == divert_port) - break; + if (inp->inp_lport != divert_port) + continue; + in_pcbref(inp); + break; + } + mtx_leave(&divb6table.inpt_mtx); + if (inp == NULL) { + div6stat_inc(div6s_noport); + goto bad; } - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_len = sizeof(addr); + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_len = sizeof(sin6); if (dir == PF_IN) { struct ifaddr *ifa; @@ -208,36 +215,34 @@ divert6_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); + div6stat_inc(div6s_errors); + goto bad; } TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { if (ifa->ifa_addr->sa_family != AF_INET6) continue; - addr.sin6_addr = satosin6(ifa->ifa_addr)->sin6_addr; + sin6.sin6_addr = satosin6(ifa->ifa_addr)->sin6_addr; break; } if_put(ifp); } - if (inp) { - sa = inp->inp_socket; - if (sbappendaddr(sa, &sa->so_rcv, sin6tosa(&addr), m, NULL) == 0) { - div6stat_inc(div6s_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, sin6tosa(&sin6), m, NULL) == 0) { + div6stat_inc(div6s_fullsock); + goto bad; } + KERNEL_LOCK(); + sorwakeup(inp->inp_socket); + KERNEL_UNLOCK(); - if (sa == NULL) { - div6stat_inc(div6s_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/netinet6/ip6_divert.h b/sys/netinet6/ip6_divert.h index 2cdac520317..709cc2aa315 100644 --- a/sys/netinet6/ip6_divert.h +++ b/sys/netinet6/ip6_divert.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_divert.h,v 1.12 2022/02/25 23:51:04 guenther Exp $ */ +/* $OpenBSD: ip6_divert.h,v 1.13 2022/05/05 16:44:22 bluhm Exp $ */ /* * Copyright (c) 2009 Michele Marchetto @@ -66,7 +66,7 @@ div6stat_inc(enum div6stat_counters c) extern struct inpcbtable divb6table; void divert6_init(void); -int divert6_packet(struct mbuf *, int, u_int16_t); +void divert6_packet(struct mbuf *, int, u_int16_t); int divert6_sysctl(int *, u_int, void *, size_t *, void *, size_t); int divert6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);