summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_pppoe.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2007-09-21 08:16:33 +0000
committermav <mav@FreeBSD.org>2007-09-21 08:16:33 +0000
commit14a66bdd4b5fb1668b671e9f8aa238fb41ae3084 (patch)
tree81451f6f9d40d6170b46d4981ef1c5779624a477 /sys/netgraph/ng_pppoe.c
parente132f56a452fd722d5cc15f703c269b40fcc87b4 (diff)
downloadFreeBSD-src-14a66bdd4b5fb1668b671e9f8aa238fb41ae3084.zip
FreeBSD-src-14a66bdd4b5fb1668b671e9f8aa238fb41ae3084.tar.gz
This patch fixes thread unsafe usage of global pkt_hdr
variable. Second part is not so important, but IMO is also good. Approved by: re (kensmith), glebius (mentor)
Diffstat (limited to 'sys/netgraph/ng_pppoe.c')
-rw-r--r--sys/netgraph/ng_pppoe.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c
index 2b91d04..3ebb1a6 100644
--- a/sys/netgraph/ng_pppoe.c
+++ b/sys/netgraph/ng_pppoe.c
@@ -1552,15 +1552,14 @@ ng_pppoe_rcvdata(hook_p hook, item_p item)
/*
* Bang in a pre-made header, and set the length up
* to be correct. Then send it to the ethernet driver.
- * But first correct the length.
*/
- sp->pkt_hdr.ph.length = htons((short)(m->m_pkthdr.len));
M_PREPEND(m, sizeof(*wh), M_DONTWAIT);
if (m == NULL)
LEAVE(ENOBUFS);
wh = mtod(m, struct pppoe_full_hdr *);
bcopy(&sp->pkt_hdr, wh, sizeof(*wh));
+ wh->ph.length = htons(m->m_pkthdr.len - sizeof(*wh));
NG_FWD_NEW_DATA( error, item, privp->ethernet_hook, m);
privp->packets_out++;
break;
@@ -1702,23 +1701,6 @@ ng_pppoe_disconnect(hook_p hook)
&& ((sp->state == PPPOE_CONNECTED)
|| (sp->state == PPPOE_NEWCONNECTED))) {
struct mbuf *m;
- struct pppoe_full_hdr *wh;
- struct pppoe_tag *tag;
- int msglen = strlen(SIGNOFF);
- int error = 0;
-
- /* Revert the stored header to DISC/PADT mode. */
- wh = &sp->pkt_hdr;
- wh->ph.code = PADT_CODE;
- /*
- * Configure ethertype depending on what was used
- * during sessions stage.
- */
- if (sp->pkt_hdr.eh.ether_type ==
- ETHERTYPE_PPPOE_3COM_SESS)
- wh->eh.ether_type = ETHERTYPE_PPPOE_3COM_DISC;
- else
- wh->eh.ether_type = ETHERTYPE_PPPOE_DISC;
/* Generate a packet of that type. */
MGETHDR(m, M_DONTWAIT, MT_DATA);
@@ -1726,15 +1708,31 @@ ng_pppoe_disconnect(hook_p hook)
log(LOG_NOTICE, "ng_pppoe[%x]: session out of "
"mbufs\n", node->nd_ID);
else {
+ struct pppoe_full_hdr *wh;
+ struct pppoe_tag *tag;
+ int msglen = strlen(SIGNOFF);
+ int error = 0;
+
m->m_pkthdr.rcvif = NULL;
m->m_pkthdr.len = m->m_len = sizeof(*wh);
- bcopy((caddr_t)wh, mtod(m, caddr_t),
- sizeof(*wh));
+ wh = mtod(m, struct pppoe_full_hdr *);
+ bcopy(&sp->pkt_hdr, wh, sizeof(*wh));
+
+ /* Revert the stored header to DISC/PADT mode. */
+ wh->ph.code = PADT_CODE;
+ /*
+ * Configure ethertype depending on what
+ * was used during sessions stage.
+ */
+ if (wh->eh.ether_type ==
+ ETHERTYPE_PPPOE_3COM_SESS)
+ wh->eh.ether_type = ETHERTYPE_PPPOE_3COM_DISC;
+ else
+ wh->eh.ether_type = ETHERTYPE_PPPOE_DISC;
/*
* Add a General error message and adjust
* sizes.
*/
- wh = mtod(m, struct pppoe_full_hdr *);
tag = wh->ph.tag;
tag->tag_type = PTT_GEN_ERR;
tag->tag_len = htons((u_int16_t)msglen);
OpenPOWER on IntegriCloud