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  *
**************************
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;
-  }
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
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to