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