QinQ support: implement details - need help!

rozhuk.im at gmail.com rozhuk.im at gmail.com
Sat Oct 22 20:22:14 UTC 2011


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

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





 
--
Rozhuk Ivan
  


> -----Original Message-----
> From: rozhuk.im at gmail.com [mailto:rozhuk.im at gmail.com]
> Sent: Saturday, October 15, 2011 4:07 AM
> To: freebsd-net at freebsd.org
> Cc: Rozhuk.IM at gmail.com
> Subject: QinQ support: implement details - need help!
> 
> 
> ...
> 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.
> 
> 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
> 
> 
> 
> "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
> 
> 
> 
> "Service Provider" VLAN - ether_type: 0x88a8/0x8100/0x9100
> How I can store it in packet?
> How to store tag for QinQinQ?
> 
> 
> 
> 
> 
> 
> VLAN tags store implementation (IMHO)
> 
> 
> Ethernet packet:
> | Dst_MAC | Src_MAC | 802.1Q_Tag2 | 802.1Q_Tag1 | 802.1Q_Tag0 |
> Ether_type/size | Payload |
> 
> 802.1Q Tag0 = "Customer" VLAN - ether_type: 0x8100, stored in
> pkthdr.PH_vt.vt_vtag (now) (IEEE 802.1Q)
> 802.1Q Tag1 = "Service Provider" / MetroTag... (IEEE 802.1ad)
> 802.1Q Tag2 = SomeTag... (QinQinQ)
> 
> 
> 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 = ntohs(evl->evl_tag);
> #else
> 	{
> 		struct m_tag *mtag;
> 		mtag = m_tag_alloc(MTAG_VLAN, MTAG_VLAN_TAG, sizeof(u_int),
> 				   M_NOWAIT);
> 		if (mtag == NULL)
> 			return;
> 		VLAN_TAG_VALUE(mtag) = ntohs(evl->evl_tag);
> 		m_tag_prepend(m, mtag);
> 	}
> 
> #endif
> 	m->m_flags |= M_VLANTAG;
> ...
> 
> 
> 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)
> 
> 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
> 
> 
> 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
> 
> #define	MTAG_VLAN_TAG1 (MTAG_VLAN_TAG0 + 1)
> #define	MTAG_VLAN_TAG2 (MTAG_VLAN_TAG1 + 1)
> #define	MTAG_VLAN_TAG3 (MTAG_VLAN_TAG2 + 1)
> 
> struct mv_tag {
> 	struct m_tag	tag;
> 	u_int16_t		vt_vtag;	/* Ethernet 802.1p+q vlan
> tag */
> };
> 
> 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
> 
> 
> 3. Extended
> Same as 2, but
> 
> 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 */
> };
> 
> 
> 
> Major question is:
> were store 802.1Q Tag0 = "Customer" VLAN (ether_type: 0x8100, IEEE
> 802.1Q):
> in pkthdr.PH_vt.vt_vtag or in struct m_tag?
> 
> 
> 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
> ...???
> 
> 
> 
> Any comments before I start?
> 
> 
> 
> 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 (...)
> 
> 
> 
> --
> Rozhuk Ivan
> 
> 




More information about the freebsd-net mailing list