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