On Mon, Jul 06, 2020 at 08:47:23PM +0200, Martin Pieuchot wrote:
> On 06/07/20(Mon) 19:23, Vitaliy Makkoveev wrote:
> > > On 6 Jul 2020, at 17:36, Martin Pieuchot <[email protected]> wrote:
> > [...]
> > Unfortunately you can’t be sure about NET_LOCK() status while you are
> > in pppac_start(). It was described at this thread [1].
> >
> > We have two cases:
> > 1. pppac_start() called from pppac_output(). NET_LOCK() was inherited.
>
> Such recursions should be avoided. if_enqueue() should take care of
> that.
I suggest to finish the route to if_get(9) before. Updated diff which
removes pipexintr() below. Just against the most resent source tree.
Index: lib/libc/sys/sysctl.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/sysctl.2,v
retrieving revision 1.40
diff -u -p -r1.40 sysctl.2
--- lib/libc/sys/sysctl.2 17 May 2020 05:48:39 -0000 1.40
+++ lib/libc/sys/sysctl.2 6 Jul 2020 21:55:16 -0000
@@ -2033,35 +2033,11 @@ The currently defined variable names are
.Bl -column "Third level name" "integer" "Changeable" -offset indent
.It Sy "Third level name" Ta Sy "Type" Ta Sy "Changeable"
.It Dv PIPEXCTL_ENABLE Ta integer Ta yes
-.It Dv PIPEXCTL_INQ Ta node Ta not applicable
-.It Dv PIPEXCTL_OUTQ Ta node Ta not applicable
.El
.Bl -tag -width "123456"
.It Dv PIPEXCTL_ENABLE
If set to 1, enable PIPEX processing.
The default is 0.
-.It Dv PIPEXCTL_INQ Pq Va net.pipex.inq
-Fourth level comprises an array of
-.Vt struct ifqueue
-structures containing information about the PIPEX packet input queue.
-The forth level names for the elements of
-.Vt struct ifqueue
-are the same as described in
-.Li ip.arpq
-in the
-.Dv PF_INET
-section.
-.It Dv PIPEXCTL_OUTQ Pq Va net.pipex.outq
-Fourth level comprises an array of
-.Vt struct ifqueue
-structures containing information about PIPEX packet output queue.
-The forth level names for the elements of
-.Vt struct ifqueue
-are the same as described in
-.Li ip.arpq
-in the
-.Dv PF_INET
-section.
.El
.El
.Ss CTL_VFS
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.611
diff -u -p -r1.611 if.c
--- sys/net/if.c 30 Jun 2020 09:31:38 -0000 1.611
+++ sys/net/if.c 6 Jul 2020 21:55:17 -0000
@@ -1012,13 +1012,6 @@ if_netisr(void *unused)
KERNEL_UNLOCK();
}
#endif
-#ifdef PIPEX
- if (n & (1 << NETISR_PIPEX)) {
- KERNEL_LOCK();
- pipexintr();
- KERNEL_UNLOCK();
- }
-#endif
t |= n;
}
Index: sys/net/netisr.h
===================================================================
RCS file: /cvs/src/sys/net/netisr.h,v
retrieving revision 1.51
diff -u -p -r1.51 netisr.h
--- sys/net/netisr.h 6 Aug 2019 22:57:54 -0000 1.51
+++ sys/net/netisr.h 6 Jul 2020 21:55:17 -0000
@@ -48,7 +48,6 @@
#define NETISR_IPV6 24 /* same as AF_INET6 */
#define NETISR_ISDN 26 /* same as AF_E164 */
#define NETISR_PPP 28 /* for PPP processing */
-#define NETISR_PIPEX 27 /* for pipex processing */
#define NETISR_BRIDGE 29 /* for bridge processing */
#define NETISR_PPPOE 30 /* for pppoe processing */
#define NETISR_SWITCH 31 /* for switch dataplane */
@@ -68,7 +67,6 @@ void bridgeintr(void);
void pppoeintr(void);
void switchintr(void);
void pfsyncintr(void);
-void pipexintr(void);
#define schednetisr(anisr)
\
do { \
Index: sys/net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.119
diff -u -p -r1.119 pipex.c
--- sys/net/pipex.c 6 Jul 2020 20:37:51 -0000 1.119
+++ sys/net/pipex.c 6 Jul 2020 21:55:17 -0000
@@ -97,10 +97,6 @@ struct radix_node_head *pipex_rd_head6 =
struct timeout pipex_timer_ch; /* callout timer context */
int pipex_prune = 1; /* walk list every seconds */
-/* pipex traffic queue */
-struct mbuf_queue pipexinq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET);
-struct mbuf_queue pipexoutq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET);
-
/* borrow an mbuf pkthdr field */
#define ph_ppp_proto ether_vtag
@@ -713,82 +709,6 @@ pipex_lookup_by_session_id(int protocol,
}
/***********************************************************************
- * Queue and Software Interrupt Handler
- ***********************************************************************/
-void
-pipexintr(void)
-{
- struct pipex_session *pkt_session;
- u_int16_t proto;
- struct mbuf *m;
- struct mbuf_list ml;
-
- /* ppp output */
- mq_delist(&pipexoutq, &ml);
- while ((m = ml_dequeue(&ml)) != NULL) {
- pkt_session = m->m_pkthdr.ph_cookie;
- if (pkt_session == NULL) {
- m_freem(m);
- continue;
- }
- proto = m->m_pkthdr.ph_ppp_proto;
-
- m->m_pkthdr.ph_cookie = NULL;
- m->m_pkthdr.ph_ppp_proto = 0;
-
- if (pkt_session->is_multicast != 0) {
- struct pipex_session *session;
- struct mbuf *m0;
-
- LIST_FOREACH(session, &pipex_session_list,
- session_list) {
- if (session->pipex_iface !=
- pkt_session->pipex_iface)
- continue;
- if (session->ip_forward == 0 &&
- session->ip6_forward == 0)
- continue;
- m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT);
- if (m0 == NULL) {
- session->stat.oerrors++;
- continue;
- }
- pipex_ppp_output(m0, session, proto);
- }
- m_freem(m);
- } else
- pipex_ppp_output(m, pkt_session, proto);
- }
-
- /* ppp input */
- mq_delist(&pipexinq, &ml);
- while ((m = ml_dequeue(&ml)) != NULL) {
- pkt_session = m->m_pkthdr.ph_cookie;
- if (pkt_session == NULL) {
- m_freem(m);
- continue;
- }
- pipex_ppp_input(m, pkt_session, 0);
- }
-}
-
-Static int
-pipex_ppp_enqueue(struct mbuf *m0, struct pipex_session *session,
- struct mbuf_queue *mq)
-{
- m0->m_pkthdr.ph_cookie = session;
- /* XXX need to support other protocols */
- m0->m_pkthdr.ph_ppp_proto = PPP_IP;
-
- if (mq_enqueue(mq, m0) != 0)
- return (1);
-
- schednetisr(NETISR_PIPEX);
-
- return (0);
-}
-
-/***********************************************************************
* Timer functions
***********************************************************************/
Static void
@@ -840,13 +760,6 @@ pipex_timer(void *ignored_arg)
/* FALLTHROUGH */
case PIPEX_STATE_CLOSED:
- /*
- * mbuf queued in pipexinq or pipexoutq may have a
- * refererce to this session.
- */
- if (!mq_empty(&pipexinq) || !mq_empty(&pipexoutq))
- continue;
-
pipex_destroy_session(session);
break;
@@ -948,8 +861,26 @@ pipex_ip_output(struct mbuf *m0, struct
m0->m_flags &= ~(M_BCAST|M_MCAST);
/* output ip packets to the session tunnel */
- if (pipex_ppp_enqueue(m0, session, &pipexoutq))
- goto dropped;
+ if (session->is_multicast != 0) {
+ struct pipex_session *session_tmp;
+ struct mbuf *m;
+
+ LIST_FOREACH(session_tmp, &pipex_session_list, session_list) {
+ if (session->pipex_iface != session_tmp->pipex_iface)
+ continue;
+ if (session_tmp->ip_forward == 0 &&
+ session_tmp->ip6_forward == 0)
+ continue;
+ m = m_copym(m0, 0, M_COPYALL, M_NOWAIT);
+ if (m == NULL) {
+ session->stat.oerrors++;
+ continue;
+ }
+ pipex_ppp_output(m, session_tmp, PPP_IP);
+ }
+ m_freem(m);
+ } else
+ pipex_ppp_output(m0, session, PPP_IP);
return;
drop:
@@ -1210,7 +1141,7 @@ pipex_ip6_input(struct mbuf *m0, struct
Static struct mbuf *
pipex_common_input(struct pipex_session *session, struct mbuf *m0, int hlen,
- int plen, int useq)
+ int plen)
{
int proto, ppphlen;
u_char code;
@@ -1258,19 +1189,11 @@ pipex_common_input(struct pipex_session
m_adj(m0, plen - m0->m_pkthdr.len);
}
- if (!useq) {
- pipex_ppp_input(m0, session, 0);
- return (NULL);
- }
-
/* input ppp packets to kernel session */
- if (pipex_ppp_enqueue(m0, session, &pipexinq) != 0)
- goto dropped;
- else
- return (NULL);
+ pipex_ppp_input(m0, session, 0);
+ return (NULL);
drop:
m_freem(m0);
-dropped:
session->stat.ierrors++;
return (NULL);
@@ -1367,7 +1290,7 @@ pipex_pppoe_input(struct mbuf *m0, struc
sizeof(struct pipex_pppoe_header), (caddr_t)&pppoe);
hlen = sizeof(struct ether_header) + sizeof(struct pipex_pppoe_header);
- if ((m0 = pipex_common_input(session, m0, hlen, ntohs(pppoe.length), 0))
+ if ((m0 = pipex_common_input(session, m0, hlen, ntohs(pppoe.length)))
== NULL)
return (NULL);
m_freem(m0);
@@ -1663,7 +1586,7 @@ pipex_pptp_input(struct mbuf *m0, struct
pipex_pptp_output(NULL, session, 0, 1);
}
- if ((m0 = pipex_common_input(session, m0, hlen, ntohs(gre->len), 1))
+ if ((m0 = pipex_common_input(session, m0, hlen, ntohs(gre->len)))
== NULL) {
/* ok, The packet is for PIPEX */
if (!rewind)
@@ -2098,7 +2021,7 @@ pipex_l2tp_input(struct mbuf *m0, int of
length -= hlen + offset;
hlen += off0 + offset;
- if ((m0 = pipex_common_input(session, m0, hlen, length, 1)) == NULL) {
+ if ((m0 = pipex_common_input(session, m0, hlen, length)) == NULL) {
/* ok, The packet is for PIPEX */
if (!rewind)
session->proto.l2tp.nr_gap += nseq;
@@ -3016,12 +2939,6 @@ pipex_sysctl(int *name, u_int namelen, v
return (ENOTDIR);
return (sysctl_int(oldp, oldlenp, newp, newlen,
&pipex_enable));
- case PIPEXCTL_INQ:
- return (sysctl_mq(name + 1, namelen - 1,
- oldp, oldlenp, newp, newlen, &pipexinq));
- case PIPEXCTL_OUTQ:
- return (sysctl_mq(name + 1, namelen - 1,
- oldp, oldlenp, newp, newlen, &pipexoutq));
default:
return (ENOPROTOOPT);
}
Index: sys/net/pipex.h
===================================================================
RCS file: /cvs/src/sys/net/pipex.h,v
retrieving revision 1.24
diff -u -p -r1.24 pipex.h
--- sys/net/pipex.h 6 Jul 2020 20:37:51 -0000 1.24
+++ sys/net/pipex.h 6 Jul 2020 21:55:17 -0000
@@ -33,15 +33,11 @@
* Names for pipex sysctl objects
*/
#define PIPEXCTL_ENABLE 1
-#define PIPEXCTL_INQ 2
-#define PIPEXCTL_OUTQ 3
-#define PIPEXCTL_MAXID 4
+#define PIPEXCTL_MAXID 2
#define PIPEXCTL_NAMES { \
{ 0, 0 }, \
{ "enable", CTLTYPE_INT }, \
- { "inq", CTLTYPE_NODE }, \
- { "outq", CTLTYPE_NODE }, \
}
#define PIPEX_PROTO_L2TP 1 /* protocol L2TP */
Index: sys/net/pipex_local.h
===================================================================
RCS file: /cvs/src/sys/net/pipex_local.h,v
retrieving revision 1.36
diff -u -p -r1.36 pipex_local.h
--- sys/net/pipex_local.h 6 Jul 2020 20:37:51 -0000 1.36
+++ sys/net/pipex_local.h 6 Jul 2020 21:55:17 -0000
@@ -402,7 +402,8 @@ void pipex_ip_input (st
#ifdef INET6
void pipex_ip6_input (struct mbuf *, struct pipex_session *);
#endif
-struct mbuf *pipex_common_input(struct pipex_session *, struct mbuf
*, int, int, int);
+struct mbuf *pipex_common_input(struct pipex_session *,
+ struct mbuf *, int, int);
#ifdef PIPEX_PPPOE
void pipex_pppoe_output (struct mbuf *, struct pipex_session
*);