'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 */