From a3425987235165177fbddd81768e37f7cb969779 Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 16 Apr 2024 12:40:40 +0000 Subject: [PATCH] Run raw IPv6 input in parallel. Get rip6_input() in the same shape as rip_input(). Call soisdisconnected() from rip6_disconnect(). This means that the raw IP socket cannot be reconnected later. Now raw IPv6 behaves like IPv4 in this regard, KAME code is quite inconsistent here. Also make sure that there is no race between disconnect, input and wakeup. The inpcb fileds inp_icmp6filt and inp_cksum6 are protected by exclusive net lock in icmp6_ctloutput(). With all that, mark raw IPv6 sockets to handle input in parallel. OK mvs@ --- sys/netinet6/in6_proto.c | 6 +++--- sys/netinet6/raw_ip6.c | 26 +++++++++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index db218af06c4..f73e00b4d2c 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -1,4 +1,4 @@ -/* $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 $ */ /* @@ -158,7 +158,7 @@ const struct protosw inet6sw[] = { .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, @@ -322,7 +322,7 @@ const struct protosw inet6sw[] = { /* 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, diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 177eeb8e88b..5804af2624f 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $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 $ */ /* @@ -155,9 +155,9 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) } 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); @@ -186,7 +186,13 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) 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)) @@ -264,7 +270,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) 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); @@ -272,12 +278,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) 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); @@ -727,7 +735,7 @@ rip6_disconnect(struct socket *so) 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); -- 2.20.1