Date: Sat, 15 Oct 2011 04:06:40 +0900 From: rozhuk.im@gmail.com To: <freebsd-net@freebsd.org> Cc: Rozhuk.IM@gmail.com Subject: QinQ support: implement details - need help! Message-ID: <4e988844.1025cc0a.1e88.ffffb4b9@mx.google.com>
next in thread | raw e-mail | index | archive | 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 =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) I found part of old code in /usr/src/sys/dev/mxge/if_mxge.c: ... /* save the tag */ #ifdef MXGE_NEW_VLAN_API=09 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); } #endif m->m_flags |=3D 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 =3D "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 (...) =A0 -- Rozhuk Ivan =A0=20
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4e988844.1025cc0a.1e88.ffffb4b9>