summaryrefslogtreecommitdiff
path: root/sys/net/if_vlan.c
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2001-03-28 00:16:29 +0000
committerJason Wright <jason@cvs.openbsd.org>2001-03-28 00:16:29 +0000
commitd8ef8d7637bbab8ce96cf7545918e0e6f04a36aa (patch)
tree49d8bb758ce1e1ab006a71876bf78d8c9295ba46 /sys/net/if_vlan.c
parentb8a3969af2ae82da33a6814be6a5b2102fa9855e (diff)
Rework vlan_start() to make sure it -never- munges the packet internals (eg.
shared mbuf clusters) Revert the deleted m_adj() call in vlan_input() back to inline mbuf manipulation, all of the checks really are there by API/convention.
Diffstat (limited to 'sys/net/if_vlan.c')
-rw-r--r--sys/net/if_vlan.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index ffd63436775..d2ff658e528 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vlan.c,v 1.14 2001/03/26 23:07:38 jason Exp $ */
+/* $OpenBSD: if_vlan.c,v 1.15 2001/03/28 00:16:28 jason Exp $ */
/*
* Copyright 1998 Massachusetts Institute of Technology
*
@@ -181,7 +181,7 @@ vlan_start(struct ifnet *ifp)
struct ifvlan *ifv;
struct ifnet *p;
struct ether_vlan_header *evl;
- struct mbuf *m;
+ struct mbuf *m, *m0;
ifv = ifp->if_softc;
p = ifv->ifv_p;
@@ -228,42 +228,44 @@ vlan_start(struct ifnet *ifp)
m->m_pkthdr.rcvif = ifp;
m->m_flags |= M_PROTO1;
} else {
- m->m_flags &= ~M_PROTO1;
- M_PREPEND(m, EVL_ENCAPLEN, M_DONTWAIT);
- if (m == NULL) {
-#ifdef DEBUG
- printf("%s: M_PREPEND failed\n",
- ifv->ifv_p->if_xname);
-#endif
+ if (m->m_len < sizeof(struct ether_header) &&
+ (m = m_pullup(m, sizeof(struct ether_header)))
+ == NULL) {
ifp->if_ierrors++;
continue;
}
- /* M_PREPEND takes care of m_len, m_pkthdr.len for us */
- m = m_pullup(m, ETHER_HDR_LEN + EVL_ENCAPLEN);
- if (m == NULL) {
-#ifdef DEBUG
- printf("%s: m_pullup failed\n",
- ifv->ifv_p->if_xname);
-#endif
+ if (m->m_flags & M_PKTHDR) {
+ MGETHDR(m0, MT_DATA, M_DONTWAIT);
+ } else {
+ MGET(m0, MT_DATA, M_DONTWAIT);
+ }
+
+ if (m0 == NULL) {
ifp->if_ierrors++;
+ m_freem(m);
continue;
}
- /*
- * Transform the Ethernet header into an Ethernet header
- * with 802.1Q encapsulation.
- */
- bcopy(mtod(m, char *) + EVL_ENCAPLEN, mtod(m, char *),
- sizeof(struct ether_header));
- evl = mtod(m, struct ether_vlan_header *);
+ if (m0->m_flags & M_PKTHDR) {
+ M_COPY_PKTHDR(m0, m);
+ m->m_flags &= ~M_PKTHDR;
+ }
+ m0->m_flags &= ~M_PROTO1;
+ m0->m_next = m;
+ m0->m_len = sizeof(struct ether_vlan_header);
+
+ evl = mtod(m0, struct ether_vlan_header *);
+ bcopy(mtod(m, char *),
+ evl, sizeof(struct ether_header));
evl->evl_proto = evl->evl_encap_proto;
evl->evl_encap_proto = htons(ETHERTYPE_8021Q);
evl->evl_tag = htons(ifv->ifv_tag);
-#ifdef DEBUG
- printf("vlan_start: %*D\n", sizeof *evl,
- (char *)evl, ":");
-#endif
+
+ m->m_len -= sizeof(struct ether_header);
+ m->m_data += sizeof(struct ether_header);
+
+ m = m0;
}
/*
@@ -371,7 +373,9 @@ vlan_input(eh, m)
*/
m->m_pkthdr.rcvif = &ifv->ifv_if;
eh->ether_type = mtod(m, u_int16_t *)[1];
- m_adj(m, EVL_ENCAPLEN);
+ m->m_len -= EVL_ENCAPLEN;
+ m->m_data += EVL_ENCAPLEN;
+ m->m_pkthdr.len -= EVL_ENCAPLEN;
#if NBPFILTER > 0
if (ifv->ifv_if.if_bpf) {