'pipex_mppe' and 'pipex_session' structures have uint16_t bit fields which represent flags. We mix unlocked access to immutable flags with protected access to mutable ones. This could be not MP independent on some architectures, so convert them fields to u_int `flags' variables.
bluhm@ pointed this when I have introduced `pxm_mtx' mutex(9), but the stack was not parallelized and all access was done with exclusive netlock. Now packet forwarding uses shared netlock and 'pipex_mppe' structure members could be accessed concurrently. So it's time to convert them. Index: sys/net/if_pppx.c =================================================================== RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.114 diff -u -p -r1.114 if_pppx.c --- sys/net/if_pppx.c 22 Feb 2022 01:15:02 -0000 1.114 +++ sys/net/if_pppx.c 21 May 2022 21:08:55 -0000 @@ -1021,7 +1021,7 @@ pppacopen(dev_t dev, int flags, int mode /* virtual pipex_session entry for multicast */ session = pool_get(&pipex_session_pool, PR_WAITOK | PR_ZERO); - session->is_multicast = 1; + session->flags |= PIPEX_SFLAGS_MULTICAST; session->ownersc = sc; sc->sc_multicast_session = session; Index: sys/net/pipex.c =================================================================== RCS file: /cvs/src/sys/net/pipex.c,v retrieving revision 1.136 diff -u -p -r1.136 pipex.c --- sys/net/pipex.c 2 Jan 2022 22:36:04 -0000 1.136 +++ sys/net/pipex.c 21 May 2022 21:08:55 -0000 @@ -150,7 +150,7 @@ pipex_destroy_all_sessions(void *ownersc LIST_FOREACH_SAFE(session, &pipex_session_list, session_list, session_tmp) { if (session->ownersc == ownersc) { - KASSERT(session->is_pppx == 0); + KASSERT((session->flags & PIPEX_SFLAGS_PPPX) == 0); pipex_unlink_session(session); pipex_rele_session(session); } @@ -273,7 +273,7 @@ pipex_init_session(struct pipex_session session->ppp_flags = req->pr_ppp_flags; session->ppp_id = req->pr_ppp_id; - session->ip_forward = 1; + session->flags |= PIPEX_SFLAGS_IP_FORWARD; session->stat_counters = counters_alloc(pxc_ncounters); @@ -395,9 +395,9 @@ pipex_link_session(struct pipex_session session->ownersc = ownersc; session->ifindex = ifp->if_index; if (ifp->if_flags & IFF_POINTOPOINT) - session->is_pppx = 1; + session->flags |= PIPEX_SFLAGS_PPPX; - if (session->is_pppx == 0 && + if ((session->flags & PIPEX_SFLAGS_PPPX) == 0 && !in_nullhost(session->ip_address.sin_addr)) { if (pipex_lookup_by_ip_address(session->ip_address.sin_addr) != NULL) @@ -439,7 +439,7 @@ pipex_unlink_session(struct pipex_sessio NET_ASSERT_LOCKED(); if (session->state == PIPEX_STATE_CLOSED) return; - if (session->is_pppx == 0 && + if ((session->flags & PIPEX_SFLAGS_PPPX) == 0 && !in_nullhost(session->ip_address.sin_addr)) { KASSERT(pipex_rd_head4 != NULL); rn = rn_delete(&session->ip_address, &session->ip_netmask, @@ -507,7 +507,11 @@ pipex_config_session(struct pipex_sessio return (EINVAL); if (session->ownersc != ownersc) return (EINVAL); - session->ip_forward = req->pcr_ip_forward; + + if (req->pcr_ip_forward != 0) + session->flags |= PIPEX_SFLAGS_IP_FORWARD; + else + session->flags &= ~PIPEX_SFLAGS_IP_FORWARD; return (0); } @@ -657,7 +661,7 @@ pipex_timer(void *ignored_arg) continue; /* Release the sessions when timeout */ pipex_unlink_session(session); - KASSERTMSG(session->is_pppx == 0, + KASSERTMSG((session->flags & PIPEX_SFLAGS_PPPX) == 0, "FIXME session must not be released when pppx"); pipex_rele_session(session); break; @@ -678,11 +682,12 @@ pipex_ip_output(struct mbuf *m0, struct { int is_idle; - if (session->is_multicast == 0) { + if ((session->flags & PIPEX_SFLAGS_MULTICAST) == 0) { /* * Multicast packet is a idle packet and it's not TCP. */ - if (session->ip_forward == 0 && session->ip6_forward == 0) + if ((session->flags & (PIPEX_SFLAGS_IP_FORWARD | + PIPEX_SFLAGS_IP6_FORWARD)) == 0) goto drop; /* reset idle timer */ if (session->timeout_sec != 0) { @@ -712,8 +717,8 @@ pipex_ip_output(struct mbuf *m0, struct LIST_FOREACH(session_tmp, &pipex_session_list, session_list) { if (session_tmp->ownersc != session->ownersc) continue; - if (session_tmp->ip_forward == 0 && - session_tmp->ip6_forward == 0) + if ((session->flags & (PIPEX_SFLAGS_IP_FORWARD | + PIPEX_SFLAGS_IP6_FORWARD)) == 0) continue; m = m_copym(m0, 0, M_COPYALL, M_NOWAIT); if (m == NULL) { @@ -838,7 +843,7 @@ pipex_ppp_input(struct mbuf *m0, struct switch (proto) { case PPP_IP: - if (session->ip_forward == 0) + if ((session->flags & PIPEX_SFLAGS_IP_FORWARD) == 0) goto drop; if (!decrypted && pipex_session_is_mppe_required(session)) /* @@ -850,7 +855,7 @@ pipex_ppp_input(struct mbuf *m0, struct return; #ifdef INET6 case PPP_IPV6: - if (session->ip6_forward == 0) + if ((session->flags & PIPEX_SFLAGS_IP6_FORWARD) == 0) goto drop; if (!decrypted && pipex_session_is_mppe_required(session)) /* @@ -2102,7 +2107,7 @@ pipex_mppe_init(struct pipex_mppe *mppe, memset(mppe, 0, sizeof(struct pipex_mppe)); mtx_init(&mppe->pxm_mtx, IPL_SOFTNET); if (stateless) - mppe->stateless = 1; + mppe->flags |= PIPEX_MPPE_STATELESS; if (has_oldkey) mppe->old_session_keys = pool_get(&mppe_key_pool, PR_WAITOK); @@ -2273,7 +2278,7 @@ pipex_mppe_input(struct mbuf *m0, struct if (coher_cnt < mppe->coher_cnt) coher_cnt0 += 0x1000; if (coher_cnt0 - mppe->coher_cnt > 0x0f00) { - if (!mppe->stateless || + if ((mppe->flags & PIPEX_MPPE_STATELESS) == 0 || coher_cnt0 - mppe->coher_cnt <= 0x1000 - PIPEX_MPPE_NOLDKEY) { pipex_session_log(session, LOG_DEBUG, @@ -2286,7 +2291,7 @@ pipex_mppe_input(struct mbuf *m0, struct } } - if (mppe->stateless != 0) { + if ((mppe->flags & PIPEX_MPPE_STATELESS) != 0) { if (!rewind) { mppe_key_change(mppe); while (mppe->coher_cnt != coher_cnt) { @@ -2407,16 +2412,16 @@ pipex_mppe_output(struct mbuf *m0, struc mtx_enter(&mppe->pxm_mtx); - if (mppe->stateless != 0) { + if ((mppe->flags & PIPEX_MPPE_STATELESS) != 0) { flushed = 1; mppe_key_change(mppe); } else { if ((mppe->coher_cnt % 0x100) == 0xff) { flushed = 1; mppe_key_change(mppe); - } else if (mppe->resetreq != 0) { + } else if ((mppe->flags & PIPEX_MPPE_RESETREQ) != 0) { flushed = 1; - mppe->resetreq = 0; + mppe->flags &= ~PIPEX_MPPE_RESETREQ; } } @@ -2478,7 +2483,7 @@ pipex_ccp_input(struct mbuf *m0, struct case CCP_RESETREQ: PIPEX_DBG((session, LOG_DEBUG, "CCP RecvResetReq")); mtx_enter(&session->mppe_send.pxm_mtx); - session->mppe_send.resetreq = 1; + session->mppe_send.flags |= PIPEX_MPPE_RESETREQ; mtx_leave(&session->mppe_send.pxm_mtx); #ifndef PIPEX_NO_CCP_RESETACK PIPEX_DBG((session, LOG_DEBUG, "CCP SendResetAck")); Index: sys/net/pipex_local.h =================================================================== RCS file: /cvs/src/sys/net/pipex_local.h,v retrieving revision 1.45 diff -u -p -r1.45 pipex_local.h --- sys/net/pipex_local.h 15 Feb 2022 03:31:17 -0000 1.45 +++ sys/net/pipex_local.h 21 May 2022 21:08:55 -0000 @@ -61,9 +61,10 @@ /* mppe rc4 key */ struct pipex_mppe { struct mutex pxm_mtx; - int16_t stateless:1, /* [I] key change mode */ - resetreq:1, /* [m] */ - reserved:14; + u_int flags; /* [m] flags, see below */ +#define PIPEX_MPPE_STATELESS 0x01 /* [I] key change mode */ +#define PIPEX_MPPE_RESETREQ 0x02 /* [m] */ + int16_t keylenbits; /* [I] key length */ int16_t keylen; /* [I] */ uint16_t coher_cnt; /* [m] coherency counter */ @@ -170,11 +171,15 @@ struct pipex_session { #define PIPEX_STATE_CLOSED 0x0004 uint32_t idle_time; /* [N] idle time in seconds */ - uint16_t ip_forward:1, /* [N] {en|dis}ableIP forwarding */ - ip6_forward:1, /* [I] {en|dis}able IPv6 forwarding */ - is_multicast:1, /* [I] virtual entry for multicast */ - is_pppx:1, /* [I] interface is point2point(pppx) */ - reserved:12; + + u_int flags; /* [N] flags, see below */ +#define PIPEX_SFLAGS_IP_FORWARD 0x01 /* [N] enable IP forwarding */ +#define PIPEX_SFLAGS_IP6_FORWARD 0x02 /* [N] enable IPv6 forwarding */ +#define PIPEX_SFLAGS_MULTICAST 0x04 /* [I] virtual entry for + multicast */ +#define PIPEX_SFLAGS_PPPX 0x08 /* [I] interface is + point2point(pppx) */ + uint16_t protocol; /* [I] tunnel protocol (PK) */ uint16_t session_id; /* [I] session-id (PK) */ uint16_t peer_session_id; /* [I] peer's session-id */