-/* $OpenBSD: netisr.h,v 1.56 2022/04/28 16:56:39 bluhm Exp $ */
+/* $OpenBSD: netisr.h,v 1.57 2022/06/28 08:01:40 mvs Exp $ */
/* $NetBSD: netisr.h,v 1.12 1995/08/12 23:59:24 mycroft Exp $ */
/*
#define NETISR_PFSYNC 5 /* for pfsync "immediate" tx */
#define NETISR_ARP 18 /* same as AF_LINK */
#define NETISR_IPV6 24 /* same as AF_INET6 */
+#define NETISR_PIPEX 27 /* for pipex processing */
#define NETISR_PPP 28 /* for PPP processing */
#define NETISR_BRIDGE 29 /* for bridge processing */
#define NETISR_SWITCH 31 /* for switch dataplane */
void bridgeintr(void);
void switchintr(void);
void pfsyncintr(void);
+void pipexintr(void);
#define schednetisr(anisr) \
do { \
-/* $OpenBSD: pipex.c,v 1.141 2022/06/26 22:51:58 mvs Exp $ */
+/* $OpenBSD: pipex.c,v 1.142 2022/06/28 08:01:40 mvs Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
#include <net/route.h>
#include <net/ppp_defs.h>
#include <net/ppp-comp.h>
+#include <net/netisr.h>
#include "pf.h"
#if NPF > 0
struct timeout pipex_timer_ch; /* callout timer context */
int pipex_prune = 1; /* [I] walk list every seconds */
+struct mbuf_queue pipexoutq = MBUF_QUEUE_INITIALIZER(
+ IFQ_MAXLEN, IPL_SOFTNET);
+
/* borrow an mbuf pkthdr field */
#define ph_ppp_proto ether_vtag
return (ret);
}
+/************************************************************************
+ * Software Interrupt Handler
+ ************************************************************************/
+
+void
+pipexintr(void)
+{
+ struct mbuf_list ml;
+ struct mbuf *m;
+ struct pipex_session *session;
+
+ NET_ASSERT_LOCKED();
+
+ mq_delist(&pipexoutq, &ml);
+
+ while ((m = ml_dequeue(&ml)) != NULL) {
+ struct ifnet *ifp;
+
+ session = m->m_pkthdr.ph_cookie;
+
+ ifp = if_get(session->proto.pppoe.over_ifidx);
+ if (ifp != NULL) {
+ struct pipex_pppoe_header *pppoe;
+ int len;
+
+ pppoe = mtod(m, struct pipex_pppoe_header *);
+ len = ntohs(pppoe->length);
+ ifp->if_output(ifp, m, &session->peer.sa, NULL);
+ counters_pkt(session->stat_counters, pxc_opackets,
+ pxc_obytes, len);
+ } else {
+ m_freem(m);
+ counters_inc(session->stat_counters, pxc_oerrors);
+ }
+ if_put(ifp);
+
+ pipex_rele_session(session);
+ }
+}
+
/************************************************************************
* Session management functions
************************************************************************/
pipex_pppoe_output(struct mbuf *m0, struct pipex_session *session)
{
struct pipex_pppoe_header *pppoe;
- struct ifnet *ifp;
int len, padlen;
/* save length for pppoe header */
pppoe->length = htons(len);
m0->m_pkthdr.ph_ifidx = session->proto.pppoe.over_ifidx;
+ refcnt_take(&session->pxs_refcnt);
+ m0->m_pkthdr.ph_cookie = session;
m0->m_flags &= ~(M_BCAST|M_MCAST);
- ifp = if_get(session->proto.pppoe.over_ifidx);
- if (ifp != NULL) {
- ifp->if_output(ifp, m0, &session->peer.sa, NULL);
- counters_pkt(session->stat_counters, pxc_opackets,
- pxc_obytes, len);
- } else {
- m_freem(m0);
+ if (mq_enqueue(&pipexoutq, m0) != 0) {
counters_inc(session->stat_counters, pxc_oerrors);
- }
- if_put(ifp);
+ pipex_rele_session(session);
+ } else
+ schednetisr(NETISR_PIPEX);
}
#endif /* PIPEX_PPPOE */