vlan Qos patch for 4.11 stable

henrysu henrysu at huisu.net
Fri Nov 4 14:05:12 PST 2005


I recently tried to set up a freebsd 4.11 stable box to do vlan Qos, and 
got one patch from earlier post, but it did not work well. I did a little 
update, and like to contribute it, in case some people want it.

You need to patch /usr/src/sbin/ifconfig and /usr/src/sys/net. Then 
rebuild the kernel and ifconfig.

Thanks.

**************************
 	Hui Su		 *
 	H: 425-644-2251	 *
**************************
-------------- next part --------------
diff -ruN ifconfig/ifconfig.8 /usr/src/sbin/ifconfig/ifconfig.8
--- ifconfig/ifconfig.8	Thu Oct 20 13:23:08 2005
+++ /usr/src/sbin/ifconfig/ifconfig.8	Thu Oct 20 13:23:49 2005
@@ -352,41 +352,21 @@
 Included for
 .Tn Solaris
 compatibility.
-.It Cm vlan Ar vlan_tag[0-4095]
+.It Cm vlan Ar vlan_tag
 If the interface is a
 .Xr vlan 4
 pseudo interface, set the VLAN tag value
 to
 .Ar vlan_tag .
-This value is a 12-bit number which is used to create an 802.1Q 
+This value is a 16-bit number which is used to create an 802.1Q
 VLAN header for packets sent from the
 .Xr vlan 4
 interface.
 Note that
-.Cm vlan, vlanpri, vlancfi
+.Cm vlan
 and
 .Cm vlandev
-must be set at the same time. 
-.It  Cm vlanpri Ar num[0-7] 
-If the interface is a 
-.Xr vlan 4 
-pseudo interface, set the 802.1p priority value 
-to 
-.Ar vlan_pri . 
-This value is a 3-bit number which is used to tag outgoing 
-VLAN packtes with apropriate priority. If 
-.Cm vlanpri 
-is omitted it default to 0. 
-.It Cm vlancfi  Ar num[0-1]
-If the interface is a 
-.Xr vlan 4 
-pseudo interface, set the CFI value 
-to 
-.Ar vlan_cfi . 
-This value is a 1-bit number which is used to tag outgoing 
-VLAN packtes with apropriate CFI value. If 
-.Cm vlancfi 
-is omitted it default to 0.
+must both be set at the same time.
 .It Cm vlandev Ar iface
 If the interface is a
 .Xr vlan 4
diff -ruN ifconfig/ifconfig.8.rej /usr/src/sbin/ifconfig/ifconfig.8.rej
--- ifconfig/ifconfig.8.rej	Thu Oct 20 13:28:40 2005
+++ /usr/src/sbin/ifconfig/ifconfig.8.rej	Wed Dec 31 16:00:00 1969
@@ -1,65 +0,0 @@
-***************
-*** 352,372 ****
-  Included for
-  .Tn Solaris
-  compatibility.
-- .It Cm vlan Ar vlan_tag
-  If the interface is a
-  .Xr vlan 4
-  pseudo interface, set the VLAN tag value
-  to
-  .Ar vlan_tag .
-- This value is a 16-bit number which is used to create an 802.1Q
-  VLAN header for packets sent from the
-  .Xr vlan 4
-  interface.
-  Note that
-- .Cm vlan
-  and
-  .Cm vlandev
-- must both be set at the same time.
-  .It Cm vlandev Ar iface
-  If the interface is a
-  .Xr vlan 4
---- 352,392 ----
-  Included for
-  .Tn Solaris
-  compatibility.
-+ .It Cm vlan Ar vlan_tag[0-4095]
-  If the interface is a
-  .Xr vlan 4
-  pseudo interface, set the VLAN tag value
-  to
-  .Ar vlan_tag .
-+ This value is a 12-bit number which is used to create an 802.1Q 
-  VLAN header for packets sent from the
-  .Xr vlan 4
-  interface.
-  Note that
-+ .Cm vlan, vlanpri, vlancfi
-  and
-  .Cm vlandev
-+ must be set at the same time. 
-+ .It  Cm vlanpri Ar num[0-7] 
-+ If the interface is a 
-+ .Xr vlan 4 
-+ pseudo interface, set the 802.1p priority value 
-+ to 
-+ .Ar vlan_pri . 
-+ This value is a 3-bit number which is used to tag outgoing 
-+ VLAN packtes with apropriate priority. If 
-+ .Cm vlanpri 
-+ is omitted it default to 0. 
-+ .It Cm vlancfi  Ar num[0-1]
-+ If the interface is a 
-+ .Xr vlan 4 
-+ pseudo interface, set the CFI value 
-+ to 
-+ .Ar vlan_cfi . 
-+ This value is a 1-bit number which is used to tag outgoing 
-+ VLAN packtes with apropriate CFI value. If 
-+ .Cm vlancfi 
-+ is omitted it default to 0.
-  .It Cm vlandev Ar iface
-  If the interface is a
-  .Xr vlan 4
diff -ruN ifconfig/ifconfig.h /usr/src/sbin/ifconfig/ifconfig.h
--- ifconfig/ifconfig.h	Thu Oct 20 13:23:08 2005
+++ /usr/src/sbin/ifconfig/ifconfig.h	Thu Oct 20 13:23:38 2005
@@ -47,8 +47,6 @@
 extern void media_status(int s, struct rt_addrinfo *);
 
 extern void setvlantag(const char *, int, int, const struct afswtch *rafp);
-extern void setvlanpri(const char *, int, int, const struct afswtch *rafp);
-extern void setvlancfi(const char *, int, int, const struct afswtch *rafp); 
 extern void setvlandev(const char *, int, int, const struct afswtch *rafp);
 extern void unsetvlandev(const char *, int, int, const struct afswtch *rafp);
 extern void vlan_status(int s, struct rt_addrinfo *);
diff -ruN ifconfig/ifconfig.h.rej /usr/src/sbin/ifconfig/ifconfig.h.rej
--- ifconfig/ifconfig.h.rej	Thu Oct 20 13:28:43 2005
+++ /usr/src/sbin/ifconfig/ifconfig.h.rej	Wed Dec 31 16:00:00 1969
@@ -1,17 +0,0 @@
-***************
-*** 47,52 ****
-  extern void media_status(int s, struct rt_addrinfo *);
-  
-  extern void setvlantag(const char *, int, int, const struct afswtch *rafp);
-  extern void setvlandev(const char *, int, int, const struct afswtch *rafp);
-  extern void unsetvlandev(const char *, int, int, const struct afswtch *rafp);
-  extern void vlan_status(int s, struct rt_addrinfo *);
---- 47,54 ----
-  extern void media_status(int s, struct rt_addrinfo *);
-  
-  extern void setvlantag(const char *, int, int, const struct afswtch *rafp);
-+ extern void setvlanpri(const char *, int, int, const struct afswtch *rafp);
-+ extern void setvlancfi(const char *, int, int, const struct afswtch *rafp); 
-  extern void setvlandev(const char *, int, int, const struct afswtch *rafp);
-  extern void unsetvlandev(const char *, int, int, const struct afswtch *rafp);
-  extern void vlan_status(int s, struct rt_addrinfo *);
diff -ruN ifconfig/ifvlan.c /usr/src/sbin/ifconfig/ifvlan.c
--- ifconfig/ifvlan.c	Thu Oct 20 13:23:08 2005
+++ /usr/src/sbin/ifconfig/ifvlan.c	Thu Oct 20 13:24:27 2005
@@ -63,9 +63,6 @@
 #endif
 static int			__tag = 0;
 static int			__have_tag = 0;
-static int			__pri = 0;
-static int                     	__cfi = 0; 
-
 
 void vlan_status(s, info)
 	int			s;
@@ -79,12 +76,9 @@
 	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
 		return;
 
-	__pri = EVL_PRIOFTAG(vreq.vlr_tag);
-	__cfi = EVL_CFIOFTAG(vreq.vlr_tag);
-	printf("\tvlan: %d 802.1p: %d CFI: %d parent interface: %s \n", 
-           EVL_VLANOFTAG(vreq.vlr_tag), EVL_PRIOFTAG(vreq.vlr_tag), 
-           EVL_CFIOFTAG(vreq.vlr_tag), 
-           vreq.vlr_parent[0] == '\0' ? "<none>" : vreq.vlr_parent ); 
+	printf("\tvlan: %d parent interface: %s\n",
+	    vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ?
+	    "<none>" : vreq.vlr_parent);
 
 	return;
 }
@@ -100,91 +94,16 @@
 	__tag = tag = atoi(val);
 	__have_tag = 1;
 
-       if (tag < 1 || tag > 4094) 
-           errx(1, "VLAN ID shoud be in range 1..4094"); 
- 
 	bzero((char *)&vreq, sizeof(struct vlanreq));
 	ifr.ifr_data = (caddr_t)&vreq;
 
 	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
 		err(1, "SIOCGETVLAN");
 
-	/* Clear old tag */
-	printf("%s: vreq.vlr_tag: %d\n", __func__, vreq.vlr_tag);
-	vreq.vlr_tag &= 0xF000;
-	vreq.vlr_tag |= tag;
-	__tag = vreq.vlr_tag;
-
-       if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
-               err(1, "SIOCSETVLAN");
-
-	return;
-}
-
-void 
-setvlanpri(const char *val, int d, int s, const struct afswtch *afp) 
-{ 
-       u_int16_t               pri; 
-       struct vlanreq          vreq; 
- 
-       __pri = pri = atoi(val); 
- 
-       if (pri > 7) 
-		errx(1, "VLAN 802.1p shoud be in range 0..7"); 
- 
-       bzero((char *)&vreq, sizeof(struct vlanreq)); 
-       ifr.ifr_data = (caddr_t)&vreq; 
- 
-       if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) 
-               err(1, "SIOCGETVLAN"); 
- 
-	pri = pri << 13;
-	
-	/* Clear pri bits */
-	vreq.vlr_tag &= 0x1FFF;
-	/* Set pri bits */
-	vreq.vlr_tag |=  pri; 
-	
-       if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) 
-               err(1, "After EVL_MAKETAG SIOCSETVLAN"); 
- 
-       return; 
-} 
-
-void 
-setvlancfi(const char *val, int d, int s, const struct afswtch *afp) 
-{ 
-       u_int16_t               cfi; 
-       struct vlanreq          vreq; 
- 
-       __cfi = cfi = atoi(val); 
- 
-	if (cfi > 1) 
-           errx(1, "VLAN CFI shoud be 0 or 1"); 
- 
-        bzero((char *)&vreq, sizeof(struct vlanreq)); 
-        ifr.ifr_data = (caddr_t)&vreq; 
-
-
-        if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) 
-                err(1, "SIOCSETVLAN"); 
-
-	/*
-        vreq.vlr_tag = EVL_MAKETAG(__tag, __pri, __cfi); 
-	*/
-
-	if (vreq.vlr_parent)
-		printf("%s: vreq.vlr_parent: %s\n", __func__, vreq.vlr_parent);
-	else
-		printf("vreq.vlr_parent is NULL\n");
-	cfi = cfi << 12;
-	/* Clear cfi bit */
-	vreq.vlr_tag &= 0xEFFF;
-	/* Set cfi bit */
-	vreq.vlr_tag |=  cfi; 
+	vreq.vlr_tag = tag;
 
-        if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) 
-                err(1, "SIOCSETVLAN"); 
+	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
+		err(1, "SIOCSETVLAN");
 
 	return;
 }
diff -ruN ifconfig/ifvlan.c.rej /usr/src/sbin/ifconfig/ifvlan.c.rej
--- ifconfig/ifvlan.c.rej	Thu Oct 20 13:28:44 2005
+++ /usr/src/sbin/ifconfig/ifvlan.c.rej	Wed Dec 31 16:00:00 1969
@@ -1,152 +0,0 @@
-***************
-*** 63,68 ****
-  #endif
-  static int			__tag = 0;
-  static int			__have_tag = 0;
-  
-  void vlan_status(s, info)
-  	int			s;
---- 63,71 ----
-  #endif
-  static int			__tag = 0;
-  static int			__have_tag = 0;
-+ static int			__pri = 0;
-+ static int                     	__cfi = 0; 
-+ 
-  
-  void vlan_status(s, info)
-  	int			s;
-***************
-*** 76,84 ****
-  	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
-  		return;
-  
-- 	printf("\tvlan: %d parent interface: %s\n",
-- 	    vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ?
-- 	    "<none>" : vreq.vlr_parent);
-  
-  	return;
-  }
---- 79,90 ----
-  	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
-  		return;
-  
-+ 	__pri = EVL_PRIOFTAG(vreq.vlr_tag);
-+ 	__cfi = EVL_CFIOFTAG(vreq.vlr_tag);
-+ 	printf("\tvlan: %d 802.1p: %d CFI: %d parent interface: %s \n", 
-+            EVL_VLANOFTAG(vreq.vlr_tag), EVL_PRIOFTAG(vreq.vlr_tag), 
-+            EVL_CFIOFTAG(vreq.vlr_tag), 
-+            vreq.vlr_parent[0] == '\0' ? "<none>" : vreq.vlr_parent ); 
-  
-  	return;
-  }
-***************
-*** 94,109 ****
-  	__tag = tag = atoi(val);
-  	__have_tag = 1;
-  
-  	bzero((char *)&vreq, sizeof(struct vlanreq));
-  	ifr.ifr_data = (caddr_t)&vreq;
-  
-  	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
-  		err(1, "SIOCGETVLAN");
-  
-- 	vreq.vlr_tag = tag;
-  
-- 	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
-- 		err(1, "SIOCSETVLAN");
-  
-  	return;
-  }
---- 100,190 ----
-  	__tag = tag = atoi(val);
-  	__have_tag = 1;
-  
-+        if (tag < 1 || tag > 4094) 
-+            errx(1, "VLAN ID shoud be in range 1..4094"); 
-+  
-  	bzero((char *)&vreq, sizeof(struct vlanreq));
-  	ifr.ifr_data = (caddr_t)&vreq;
-  
-  	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
-  		err(1, "SIOCGETVLAN");
-  
-+ 	/* Clear old tag */
-+ 	printf("%s: vreq.vlr_tag: %d\n", __func__, vreq.vlr_tag);
-+ 	vreq.vlr_tag &= 0xF000;
-+ 	vreq.vlr_tag |= tag;
-+ 	__tag = vreq.vlr_tag;
-+ 
-+        if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
-+                err(1, "SIOCSETVLAN");
-+ 
-+ 	return;
-+ }
-+ 
-+ void 
-+ setvlanpri(const char *val, int d, int s, const struct afswtch *afp) 
-+ { 
-+        u_int16_t               pri; 
-+        struct vlanreq          vreq; 
-+  
-+        __pri = pri = atoi(val); 
-+  
-+        if (pri > 7) 
-+ 		errx(1, "VLAN 802.1p shoud be in range 0..7"); 
-+  
-+        bzero((char *)&vreq, sizeof(struct vlanreq)); 
-+        ifr.ifr_data = (caddr_t)&vreq; 
-+  
-+        if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) 
-+                err(1, "SIOCGETVLAN"); 
-+  
-+ 	pri = pri << 13;
-+ 	
-+ 	/* Clear pri bits */
-+ 	vreq.vlr_tag &= 0x1FFF;
-+ 	/* Set pri bits */
-+ 	vreq.vlr_tag |=  pri; 
-+ 	
-+        if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) 
-+                err(1, "After EVL_MAKETAG SIOCSETVLAN"); 
-+  
-+        return; 
-+ } 
-+ 
-+ void 
-+ setvlancfi(const char *val, int d, int s, const struct afswtch *afp) 
-+ { 
-+        u_int16_t               cfi; 
-+        struct vlanreq          vreq; 
-+  
-+        __cfi = cfi = atoi(val); 
-+  
-+ 	if (cfi > 1) 
-+            errx(1, "VLAN CFI shoud be 0 or 1"); 
-+  
-+         bzero((char *)&vreq, sizeof(struct vlanreq)); 
-+         ifr.ifr_data = (caddr_t)&vreq; 
-+ 
-+ 
-+         if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) 
-+                 err(1, "SIOCSETVLAN"); 
-+ 
-+ 	/*
-+         vreq.vlr_tag = EVL_MAKETAG(__tag, __pri, __cfi); 
-+ 	*/
-+ 
-+ 	if (vreq.vlr_parent)
-+ 		printf("%s: vreq.vlr_parent: %s\n", __func__, vreq.vlr_parent);
-+ 	else
-+ 		printf("vreq.vlr_parent is NULL\n");
-+ 	cfi = cfi << 12;
-+ 	/* Clear cfi bit */
-+ 	vreq.vlr_tag &= 0xEFFF;
-+ 	/* Set cfi bit */
-+ 	vreq.vlr_tag |=  cfi; 
-  
-+         if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) 
-+                 err(1, "SIOCSETVLAN"); 
-  
-  	return;
-  }
-------------- next part --------------
diff -ruN /usr/src/sys/net/if_vlan.c net.patch/if_vlan.c
--- /usr/src/sys/net/if_vlan.c	Thu Oct 20 14:21:05 2005
+++ net.patch/if_vlan.c	Thu Oct 20 14:20:49 2005
@@ -443,7 +443,7 @@
 	for (ifv = LIST_FIRST(&ifv_list); ifv != NULL;
 	    ifv = LIST_NEXT(ifv, ifv_list)) {
 		if (m->m_pkthdr.rcvif == ifv->ifv_p
-		    && ifv->ifv_tag == EVL_VLANOFTAG(t))
+		    && EVL_VLANOFTAG(ifv->ifv_tag) == EVL_VLANOFTAG(t))
 			break;
 	}
 
@@ -473,7 +473,7 @@
 	    ifv = LIST_NEXT(ifv, ifv_list)) {
 		if (m->m_pkthdr.rcvif == ifv->ifv_p
 		    && (EVL_VLANOFTAG(ntohs(*mtod(m, u_int16_t *)))
-			== ifv->ifv_tag))
+			== EVL_VLANOFTAG(ifv->ifv_tag))) /* Must mask it, since we have priority bit and cfi */
 			break;
 	}
 
@@ -509,7 +509,8 @@
 
 	if (p->if_data.ifi_type != IFT_ETHER)
 		return EPROTONOSUPPORT;
-	if (ifv->ifv_p)
+	printf("VLAN DEBUG: p %p  ifv->ifv_p %p\n", p, ifv->ifv_p);
+	if (ifv->ifv_p && (ifv->ifv_p != p))
 		return EBUSY;
 	ifv->ifv_p = p;
 	if (p->if_data.ifi_hdrlen == sizeof(struct ether_vlan_header))
@@ -679,10 +680,11 @@
 		error = copyin(ifr->ifr_data, &vlr, sizeof vlr);
 		if (error)
 			break;
-		if (vlr.vlr_tag & ~EVL_VLID_MASK) {
+		if (EVL_VLANOFTAG(vlr.vlr_tag) & ~EVL_VLID_MASK) {
 			error = EINVAL;
 			break;
 		}
+		/* No parent destroy it */
 		if (vlr.vlr_parent[0] == '\0') {
 			vlan_unconfig(ifp);
 			if (ifp->if_flags & IFF_UP) {
diff -ruN /usr/src/sys/net/if_vlan_var.h net.patch/if_vlan_var.h
--- /usr/src/sys/net/if_vlan_var.h	Thu Oct 20 14:21:05 2005
+++ net.patch/if_vlan_var.h	Thu Oct 20 14:20:49 2005
@@ -66,6 +66,8 @@
 #define	EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK)
 #define	EVL_PRIOFTAG(tag) (((tag) >> 13) & 7)
 #define	EVL_ENCAPLEN	4	/* length in octets of encapsulation */
+#define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1) 
+#define EVL_MAKETAG(vlid,pri,cfi) ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) 
 
 /* sysctl(3) tags, for compatibility purposes */
 #define	VLANCTL_PROTO	1
@@ -75,8 +77,8 @@
  * Configuration structure for SIOCSETVLAN and SIOCGETVLAN ioctls.
  */
 struct	vlanreq {
-	char	vlr_parent[IFNAMSIZ];
-	u_short	vlr_tag;
+       char            vlr_parent[IFNAMSIZ]; 
+       u_int16_t       vlr_tag; 
 };
 #define	SIOCSETVLAN	SIOCSIFGENERIC
 #define	SIOCGETVLAN	SIOCGIFGENERIC


More information about the freebsd-net mailing list