Skip site navigation (1)Skip section navigation (2)
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>