Date: Thu, 19 Oct 2000 23:11:35 +0900 From: MIHIRA Sanpei Yoshiro <sanpei@sanpei.org> To: freebsd-net@FreeBSD.ORG Subject: [Patch] VLAN MTU1500 patch for FreeBSD 4.1-RELEASE and later Message-ID: <200010191411.e9JEBZ817011@lavender.sanpei.org>
next in thread | raw e-mail | index | archive | help
Hi.
This is VLAN MTU1500 patch for FreeBSD 4.1-RELEASE and
later(sorry, I did not test under 5-current). This patch was created
by HOSOKAWA Tatsumi-san(hosokawa@FreeBSD.org), but he was too busy
to announce and commit. So I post this patch by proxy.
This patch was tested:
- with Intel PRO/100+ Management Adapter(fxp)
- with Netgear Gigabit Ethernet (MM SC) GA-620
And we will use other NICs which support VLAN packet.
Cheers.
---
MIHIRA, Sanpei Yoshiro
Yokohama, Japan.
diff -urN ../src/sys/net/if_ethersubr.c sys/net/if_ethersubr.c
--- ../src/sys/net/if_ethersubr.c Tue Jul 18 06:24:34 2000
+++ sys/net/if_ethersubr.c Thu Sep 21 20:50:41 2000
@@ -139,12 +139,26 @@
u_char esrc[6], edst[6];
register struct rtentry *rt;
register struct ether_header *eh;
+#if NVLAN > 0
+ register struct ether_vlan_header *evh = NULL;
+ register struct ifvlan *ifv = NULL;
+#endif /* NVLAN > 0 */
+ register struct ifnet *ifp_s;
int off, loop_copy = 0;
int hlen; /* link layer header lenght */
struct arpcom *ac = IFP2AC(ifp);
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
senderr(ENETDOWN);
+ ifp_s = ifp;
+#if NVLAN > 0
+ if (ifp->if_data.ifi_type == IFT_8021_VLAN) {
+ ifv = ifp->if_softc;
+ ifp_s = ifv->ifv_p;
+ if ((ifp_s->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ senderr(ENETDOWN);
+ }
+#endif /* NVLAN > 0 */
rt = rt0;
if (rt) {
if ((rt->rt_flags & RTF_UP) == 0) {
@@ -171,6 +185,10 @@
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
}
hlen = ETHER_HDR_LEN;
+#if NVLAN > 0
+ if (ifv != NULL)
+ hlen += EVL_ENCAPLEN;
+#endif /* NVLAN > 0 */
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
@@ -229,6 +247,10 @@
bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
type = htons(m->m_pkthdr.len);
hlen = sizeof(struct llc) + ETHER_HDR_LEN;
+#if NVLAN > 0
+ if (ifv != NULL)
+ hlen += EVL_ENCAPLEN;
+#endif /* NVLAN > 0 */
} else {
type = htons(ETHERTYPE_AT);
}
@@ -304,19 +326,39 @@
* Add local net header. If no space in first mbuf,
* allocate another.
*/
- M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
- if (m == 0)
- senderr(ENOBUFS);
- eh = mtod(m, struct ether_header *);
- (void)memcpy(&eh->ether_type, &type,
- sizeof(eh->ether_type));
- (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
- if (hdrcmplt)
- (void)memcpy(eh->ether_shost, esrc,
- sizeof(eh->ether_shost));
- else
- (void)memcpy(eh->ether_shost, ac->ac_enaddr,
- sizeof(eh->ether_shost));
+#if NVLAN > 0
+ if (ifp->if_data.ifi_type == IFT_8021_VLAN) {
+ M_PREPEND(m, sizeof (struct ether_vlan_header), M_DONTWAIT);
+ if (m == 0)
+ senderr(ENOBUFS);
+ evh = mtod(m, struct ether_vlan_header *);
+ eh = (struct ether_header *) evh;
+ /*(void)memcpy(&evh->evl_encap_proto, &htons(vlan_proto),
+ sizeof(evh->evl_encap_proto));*/
+ evh->evl_encap_proto = htons(vlan_proto);
+ evh->evl_tag = htons(ifv->ifv_tag);
+ (void)memcpy(&evh->evl_proto, &type, sizeof(evh->evl_proto));
+ (void)memcpy(evh->evl_dhost, edst, sizeof(evh->evl_dhost));
+ (void)memcpy(evh->evl_shost, ac->ac_enaddr, sizeof(evh->evl_shost));
+ }
+ else {
+#endif /* NVLAN > 0 */
+ M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
+ if (m == 0)
+ senderr(ENOBUFS);
+ eh = mtod(m, struct ether_header *);
+ (void)memcpy(&eh->ether_type, &type,
+ sizeof(eh->ether_type));
+ (void)memcpy(eh->ether_dhost, edst, sizeof (edst));
+ if (hdrcmplt)
+ (void)memcpy(eh->ether_shost, esrc,
+ sizeof(eh->ether_shost));
+ else
+ (void)memcpy(eh->ether_shost, ac->ac_enaddr,
+ sizeof(eh->ether_shost));
+#if NVLAN > 0
+ }
+#endif /* NVLAN > 0 */
/*
* If a simplex interface, and the packet is being sent to our
@@ -366,7 +408,24 @@
struct mbuf *m;
{
int s, error = 0;
+ int len = m->m_pkthdr.len;
+#if NVLAN > 0
+ register struct ifvlan *ifv = NULL;
+#endif /* NVLAN > 0 */
+ register struct ifnet *ifp_s;
+ ifp_s = ifp;
+#if NVLAN > 0
+ if (ifp->if_data.ifi_type == IFT_8021_VLAN) {
+ ifv = ifp->if_softc;
+ ifp_s = ifv->ifv_p;
+ if ((ifp_s->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
+ if (m != NULL)
+ m_freem(m);
+ return (ENETDOWN);
+ }
+ }
+#endif /* NVLAN > 0 */
#ifdef BRIDGE
if (do_bridge) {
struct ether_header hdr;
@@ -387,19 +446,31 @@
* Queue message on interface, and start output if interface
* not yet active.
*/
- if (IF_QFULL(&ifp->if_snd)) {
- IF_DROP(&ifp->if_snd);
+ if (IF_QFULL(&ifp_s->if_snd)) {
+ IF_DROP(&ifp_s->if_snd);
splx(s);
m_freem(m);
return (ENOBUFS);
}
- ifp->if_obytes += m->m_pkthdr.len;
+ ifp_s->if_obytes += m->m_pkthdr.len;
if (m->m_flags & M_MCAST)
- ifp->if_omcasts++;
- IF_ENQUEUE(&ifp->if_snd, m);
- if ((ifp->if_flags & IFF_OACTIVE) == 0)
- (*ifp->if_start)(ifp);
+ ifp_s->if_omcasts++;
+ IF_ENQUEUE(&ifp_s->if_snd, m);
+ if ((ifp_s->if_flags & IFF_OACTIVE) == 0)
+ (*ifp_s->if_start)(ifp_s);
splx(s);
+#if NVLAN > 0
+ if (ifv != NULL) {
+ ifp->if_obytes += len + sizeof (struct ether_vlan_header);
+ ifp_s->if_obytes += len + sizeof (struct ether_vlan_header);
+ } else {
+ ifp_s->if_obytes += len + sizeof (struct ether_header);
+ }
+#else /* NVLAN > 0 */
+ ifp_s->if_obytes += len + sizeof (struct ether_header);
+ if (m->m_flags & M_MCAST)
+ ifp_s->if_omcasts++;
+#endif /* NVLAN > 0 */
return (error);
}
@@ -633,6 +704,8 @@
#endif /* NETATALK */
}
+ /* XXXX */
+ /*printf("ether_input: encolando el paquete\n");*/
s = splimp();
if (IF_QFULL(inq)) {
IF_DROP(inq);
diff -urN ../src/sys/net/if_vlan.c sys/net/if_vlan.c
--- ../src/sys/net/if_vlan.c Tue Jul 18 06:24:34 2000
+++ sys/net/if_vlan.c Thu Sep 21 16:37:48 2000
@@ -356,10 +356,10 @@
if (ifv->ifv_p)
return EBUSY;
ifv->ifv_p = p;
- if (p->if_data.ifi_hdrlen == sizeof(struct ether_vlan_header))
+ /*if (p->if_data.ifi_hdrlen == sizeof(struct ether_vlan_header))*/
ifv->ifv_if.if_mtu = p->if_mtu;
- else
- ifv->ifv_if.if_mtu = p->if_data.ifi_mtu - EVL_ENCAPLEN;
+ /*else
+ ifv->ifv_if.if_mtu = p->if_data.ifi_mtu - EVL_ENCAPLEN;*/
/*
* Preserve the state of the LINK0 flag for ourselves.
diff -urN ../src/sys/pci/if_fxp.c sys/pci/if_fxp.c
--- ../src/sys/pci/if_fxp.c Wed Jul 19 23:36:36 2000
+++ sys/pci/if_fxp.c Thu Sep 21 20:24:54 2000
@@ -34,6 +34,9 @@
* Intel EtherExpress Pro/100B PCI Fast Ethernet driver
*/
+#if !defined(KLD_MODULE)
+#include "vlan.h"
+#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@@ -52,6 +55,12 @@
#include <net/bpf.h>
+#if NVLAN > 0
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/if_vlan_var.h>
+#endif /* NVLAN > 0 */
+
#if defined(__NetBSD__)
#include <sys/ioctl.h>
@@ -1177,7 +1186,19 @@
total_len = rfa->actual_size &
(MCLBYTES - 1);
if (total_len <
+#if NVLAN > 0
+ sizeof(struct ether_vlan_header)) {
+#else
sizeof(struct ether_header)) {
+#endif /* NVLAN > 0 */
+ m_freem(m);
+ goto rcvloop;
+ }
+ /*
+ * Drop the packet if it has CRC
+ * errors.
+ */
+ if (rfa->rfa_status & FXP_RFA_STATUS_CRC) {
m_freem(m);
goto rcvloop;
}
@@ -1460,7 +1481,11 @@
cbp->late_scb = 0; /* (don't) defer SCB update */
cbp->tno_int = 0; /* (disable) tx not okay interrupt */
cbp->ci_int = 1; /* interrupt on CU idle */
+#if NVLAN > 0
+ cbp->save_bf = 1; /* always save bad frames XXX */
+#else /* NVLAN > 0 */
cbp->save_bf = prm; /* save bad frames */
+#endif
cbp->disc_short_rx = !prm; /* discard short packets */
cbp->underrun_retry = 1; /* retry mode (1) on DMA underrun */
cbp->mediatype = !sc->phy_10Mbps_only; /* interface mode */
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200010191411.e9JEBZ817011>
