Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Oct 2011 05:22:08 +0900
From:      rozhuk.im@gmail.com
To:        <Rozhuk.IM@gmail.com>, <freebsd-net@freebsd.org>
Subject:   RE: QinQ support: implement details - need help!
Message-ID:  <4ea325f3.4693cc0a.45c2.6fc5@mx.google.com>
In-Reply-To: <4e988844.1025cc0a.1e88.ffffb4b9@mx.google.com>
References:  <4e988844.1025cc0a.1e88.ffffb4b9@mx.google.com>

next in thread | previous in thread | raw e-mail | index | archive | help

http://www.freebsd.org/cgi/query-pr.cgi?pr=3D161908

All done.
IEEE 802.1Q + IEEE 802.1p
IEEE 802.1ad (IEEE 802.1QinQ) - if two ng_vlan node


+ ethernet_type for VLAN encapsulation is tunable, default is: 0x8100
(33024)
+ PCP (Priority Code Point) and CFI (Canonical Format Indicator) for =
VLAN
encapsulation is tunable per VID
+ VLAN filter can be deleted by VID
+ tunable encapsulation: on - do 802.1Q encapsulation, off - set =
M_VLANTAG
and ether_vtag
* improved encapsulation/decapsulation code
* "vlan" changed to "vid" in "addfilter" and "gettable" messages
* many other changes





=A0
--
Rozhuk Ivan
=A0=20


> -----Original Message-----
> From: rozhuk.im@gmail.com [mailto:rozhuk.im@gmail.com]
> Sent: Saturday, October 15, 2011 4:07 AM
> To: freebsd-net@freebsd.org
> Cc: Rozhuk.IM@gmail.com
> Subject: QinQ support: implement details - need help!
>=20
>=20
> ...
> IEEE 802.1ad (802.1QinQ) specifies architecture and bridge protocols =
to
> provide separate instances of the MAC services to multiple independent
> users
> of a Bridged Local Area Network in a manner that does not require
> cooperation among the users, and requires a minimum of cooperation
> between
> the users and the provider of the MAC service.
>=20
> The idea is to provide, for example, the possibility for customers to
> run
> their own VLANs inside service provider's provided VLAN. This way the
> service provider can just configure one VLAN for the customer and
> customer
> can then treat that VLAN as if it was a trunk.
> ...
> http://en.wikipedia.org/wiki/802.1ad
>=20
>=20
>=20
> "Customer" VLAN - ether_type: 0x8100
> Stored in:
> struct pkthdr {
> ...
> 	union {
> 		u_int16_t vt_vtag;	/* Ethernet 802.1p+q vlan tag */
> 		u_int16_t vt_nrecs;	/* # of IGMPv3 records in this chain
> */
> 	} PH_vt;
> 	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
> };
> #define ether_vtag	PH_vt.vt_vtag
>=20
>=20
>=20
> "Service Provider" VLAN - ether_type: 0x88a8/0x8100/0x9100
> How I can store it in packet?
> How to store tag for QinQinQ?
>=20
>=20
>=20
>=20
>=20
>=20
> VLAN tags store implementation (IMHO)
>=20
>=20
> Ethernet packet:
> | Dst_MAC | Src_MAC | 802.1Q_Tag2 | 802.1Q_Tag1 | 802.1Q_Tag0 |
> Ether_type/size | Payload |
>=20
> 802.1Q Tag0 =3D "Customer" VLAN - ether_type: 0x8100, stored in
> pkthdr.PH_vt.vt_vtag (now) (IEEE 802.1Q)
> 802.1Q Tag1 =3D "Service Provider" / MetroTag... (IEEE 802.1ad)
> 802.1Q Tag2 =3D SomeTag... (QinQinQ)
>=20
>=20
> I found part of old code in /usr/src/sys/dev/mxge/if_mxge.c:
> ...
> 	/* save the tag */
> #ifdef MXGE_NEW_VLAN_API
> 	m->m_pkthdr.ether_vtag =3D ntohs(evl->evl_tag);
> #else
> 	{
> 		struct m_tag *mtag;
> 		mtag =3D m_tag_alloc(MTAG_VLAN, MTAG_VLAN_TAG, sizeof(u_int),
> 				   M_NOWAIT);
> 		if (mtag =3D=3D NULL)
> 			return;
> 		VLAN_TAG_VALUE(mtag) =3D ntohs(evl->evl_tag);
> 		m_tag_prepend(m, mtag);
> 	}
>=20
> #endif
> 	m->m_flags |=3D M_VLANTAG;
> ...
>=20
>=20
> 1. Compact scheme:
> #define	MTAG_VLAN_T0	1035328035 /* m_tag_cookie */
> #define	MTAG_VLAN_T1	(MTAG_VLAN_T0 + 1)
> #define	MTAG_VLAN_T2	(MTAG_VLAN_T1 + 1)
> #define	MTAG_VLAN_T3	(MTAG_VLAN_T2 + 1)
>=20
> Store vt_vtag in m_tag_id
> ng_vlan / if_vlan will use for tag/untag one of MTAG_VLAN_Tx
> m_tag_cookie
> and tunable ether_type for vlan encapsulation:
> lower <-> ng_vlan(MTAG_VLAN_T0) <-> ng_vlan(MTAG_VLAN_T1) <->
> ng_vlan(MTAG_VLAN_T2) <-> upper
>=20
>=20
> 2. OpenBSD compatible
> #ifdef <OPENBSD>
> #define	MTAG_VLAN		MTAG_ABI_COMPAT /* cookie */
> #define	MTAG_VLAN_TAG0	1035328035
> #else
> #define	MTAG_VLAN		1035328035	/* m_tag_cookie */
> #define	MTAG_VLAN_TAG0	0		/* tag of VLAN interface */
> #endif
>=20
> #define	MTAG_VLAN_TAG1 (MTAG_VLAN_TAG0 + 1)
> #define	MTAG_VLAN_TAG2 (MTAG_VLAN_TAG1 + 1)
> #define	MTAG_VLAN_TAG3 (MTAG_VLAN_TAG2 + 1)
>=20
> struct mv_tag {
> 	struct m_tag	tag;
> 	u_int16_t		vt_vtag;	/* Ethernet 802.1p+q vlan
> tag */
> };
>=20
> ng_vlan / if_vlan will use for tag/untag one of MTAG_VLAN_TAGx =
m_tag_id
> and
> tunable ether_type for vlan encapsulation:
> lower <-> ng_vlan(MTAG_VLAN_TAG0) <-> ng_vlan(MTAG_VLAN_TAG1) <->
> ng_vlan(MTAG_VLAN_TAG2) <-> upper
>=20
>=20
> 3. Extended
> Same as 2, but
>=20
> struct mv_tag {
> 	struct m_tag	tag;
> 	u_int16_t		vt_vtag;	/* Ethernet 802.1p+q vlan
> tag */
> 	u_int16_t		ether_type;	/* Ethernet type for TAG */
> };
>=20
>=20
>=20
> Major question is:
> were store 802.1Q Tag0 =3D "Customer" VLAN (ether_type: 0x8100, IEEE
> 802.1Q):
> in pkthdr.PH_vt.vt_vtag or in struct m_tag?
>=20
>=20
> ng_vlan modifications (I can make):
> + tunable ether_type for vlan encapsulation
> + tunable on/off encapsulation (to prevent network adapter
> encapsulation)
> + tunable m_tag identifier for VLAN tag
> ...???
>=20
>=20
>=20
> Any comments before I start?
>=20
>=20
>=20
> PS: Trick:
> kern.ipc.max_linkhdr should be increased via sysctl:
> 20 - 1 VLAN tag (.Q)
> 24 - 2 VLAN tags (QinQ)
> 28 - 3 VLAN tags (QinQinQ)
> 32 - 4 VLAN tags (...)
>=20
>=20
>=20
> --
> Rozhuk Ivan
>=20
>=20





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4ea325f3.4693cc0a.45c2.6fc5>