-/* $OpenBSD: in6_proto.c,v 1.113 2024/01/11 14:15:12 bluhm Exp $ */
+/* $OpenBSD: in6_proto.c,v 1.114 2024/04/16 12:40:40 bluhm Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/*
.pr_type = SOCK_RAW,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_RAW,
- .pr_flags = PR_ATOMIC|PR_ADDR,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
.pr_input = rip6_input,
.pr_ctlinput = rip6_ctlinput,
.pr_ctloutput = rip6_ctloutput,
/* raw wildcard */
.pr_type = SOCK_RAW,
.pr_domain = &inet6domain,
- .pr_flags = PR_ATOMIC|PR_ADDR,
+ .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
.pr_input = rip6_input,
.pr_ctloutput = rip6_ctloutput,
.pr_usrreqs = &rip6_usrreqs,
-/* $OpenBSD: raw_ip6.c,v 1.182 2024/02/13 12:22:09 bluhm Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.183 2024/04/16 12:40:40 bluhm Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
} else
rip6stat_inc(rip6s_ipackets);
- bzero(&rip6src, sizeof(rip6src));
- rip6src.sin6_len = sizeof(struct sockaddr_in6);
+ memset(&rip6src, 0, sizeof(rip6src));
rip6src.sin6_family = AF_INET6;
+ rip6src.sin6_len = sizeof(rip6src);
/* KAME hack: recover scopeid */
in6_recoverscope(&rip6src, &ip6->ip6_src);
TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, inp_queue) {
KASSERT(ISSET(inp->inp_flags, INP_IPV6));
- if (inp->inp_socket->so_rcv.sb_state & SS_CANTRCVMORE)
+ /*
+ * Packet must not be inserted after disconnected wakeup
+ * call. To avoid race, check again when holding receive
+ * buffer mutex.
+ */
+ if (ISSET(READ_ONCE(inp->inp_socket->so_rcv.sb_state),
+ SS_CANTRCVMORE))
continue;
if (rtable_l2(inp->inp_rtableid) !=
rtable_l2(m->m_pkthdr.ph_rtableid))
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL) {
struct socket *so = inp->inp_socket;
- int ret;
+ int ret = 0;
if (inp->inp_flags & IN6P_CONTROLOPTS)
ip6_savecontrol(inp, n, &opts);
m_adj(n, *offp);
mtx_enter(&so->so_rcv.sb_mtx);
- ret = sbappendaddr(so, &so->so_rcv,
- sin6tosa(&rip6src), n, opts);
+ if (!ISSET(inp->inp_socket->so_rcv.sb_state,
+ SS_CANTRCVMORE)) {
+ ret = sbappendaddr(so, &so->so_rcv,
+ sin6tosa(&rip6src), n, opts);
+ }
mtx_leave(&so->so_rcv.sb_mtx);
if (ret == 0) {
- /* should notify about lost packet */
m_freem(n);
m_freem(opts);
rip6stat_inc(rip6s_fullsock);
if ((so->so_state & SS_ISCONNECTED) == 0)
return (ENOTCONN);
- so->so_state &= ~SS_ISCONNECTED; /* XXX */
+ soisdisconnected(so);
mtx_enter(&rawin6pcbtable.inpt_mtx);
inp->inp_faddr6 = in6addr_any;
mtx_leave(&rawin6pcbtable.inpt_mtx);