1139823Simp/*-
234649Swollman * Copyright 1998 Massachusetts Institute of Technology
334649Swollman *
434649Swollman * Permission to use, copy, modify, and distribute this software and
534649Swollman * its documentation for any purpose and without fee is hereby
634649Swollman * granted, provided that both the above copyright notice and this
734649Swollman * permission notice appear in all copies, that both the above
834649Swollman * copyright notice and this permission notice appear in all
934649Swollman * supporting documentation, and that the name of M.I.T. not be used
1034649Swollman * in advertising or publicity pertaining to distribution of the
1134649Swollman * software without specific, written prior permission.  M.I.T. makes
1234649Swollman * no representations about the suitability of this software for any
1334649Swollman * purpose.  It is provided "as is" without express or implied
1434649Swollman * warranty.
1534649Swollman *
1634649Swollman * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
1734649Swollman * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
1834649Swollman * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1934649Swollman * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
2034649Swollman * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2134649Swollman * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2234649Swollman * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2334649Swollman * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2434649Swollman * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2534649Swollman * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2634649Swollman * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2734649Swollman * SUCH DAMAGE.
2834649Swollman *
2950477Speter * $FreeBSD$
3034649Swollman */
3134649Swollman
3234649Swollman#ifndef _NET_IF_VLAN_VAR_H_
3334649Swollman#define	_NET_IF_VLAN_VAR_H_	1
3434649Swollman
3534649Swollmanstruct	ether_vlan_header {
3634649Swollman	u_char	evl_dhost[ETHER_ADDR_LEN];
3734649Swollman	u_char	evl_shost[ETHER_ADDR_LEN];
3834649Swollman	u_int16_t evl_encap_proto;
3934649Swollman	u_int16_t evl_tag;
4034649Swollman	u_int16_t evl_proto;
4134649Swollman};
4234649Swollman
43167126Sbms#define	EVL_VLID_MASK		0x0FFF
44167126Sbms#define	EVL_PRI_MASK		0xE000
45167126Sbms#define	EVL_VLANOFTAG(tag)	((tag) & EVL_VLID_MASK)
46167126Sbms#define	EVL_PRIOFTAG(tag)	(((tag) >> 13) & 7)
47167126Sbms#define	EVL_CFIOFTAG(tag)	(((tag) >> 12) & 1)
48167126Sbms#define	EVL_MAKETAG(vlid, pri, cfi)					\
49167126Sbms	((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK))
5034649Swollman
51167126Sbms/* Set the VLAN ID in an mbuf packet header non-destructively. */
52167126Sbms#define EVL_APPLY_VLID(m, vlid)						\
53167126Sbms	do {								\
54167126Sbms		if ((m)->m_flags & M_VLANTAG) {				\
55167126Sbms			(m)->m_pkthdr.ether_vtag &= EVL_VLID_MASK;	\
56167126Sbms			(m)->m_pkthdr.ether_vtag |= (vlid);		\
57167126Sbms		} else {						\
58167126Sbms			(m)->m_pkthdr.ether_vtag = (vlid);		\
59167126Sbms			(m)->m_flags |= M_VLANTAG;			\
60167126Sbms		}							\
61167126Sbms	} while (0)
62167126Sbms
63167126Sbms/* Set the priority ID in an mbuf packet header non-destructively. */
64167126Sbms#define EVL_APPLY_PRI(m, pri)						\
65167126Sbms	do {								\
66167126Sbms		if ((m)->m_flags & M_VLANTAG) {				\
67167126Sbms			uint16_t __vlantag = (m)->m_pkthdr.ether_vtag;	\
68167126Sbms			(m)->m_pkthdr.ether_vtag |= EVL_MAKETAG(	\
69167126Sbms			    EVL_VLANOFTAG(__vlantag), (pri),		\
70167126Sbms			    EVL_CFIOFTAG(__vlantag));			\
71167126Sbms		} else {						\
72167126Sbms			(m)->m_pkthdr.ether_vtag =			\
73167126Sbms			    EVL_MAKETAG(0, (pri), 0);			\
74167126Sbms			(m)->m_flags |= M_VLANTAG;			\
75167126Sbms		}							\
76167126Sbms	} while (0)
77167126Sbms
7834649Swollman/* sysctl(3) tags, for compatibility purposes */
7934649Swollman#define	VLANCTL_PROTO	1
8034649Swollman#define	VLANCTL_MAX	2
8134649Swollman
8234649Swollman/*
8334649Swollman * Configuration structure for SIOCSETVLAN and SIOCGETVLAN ioctls.
8434649Swollman */
8534649Swollmanstruct	vlanreq {
8634649Swollman	char	vlr_parent[IFNAMSIZ];
8734649Swollman	u_short	vlr_tag;
8834649Swollman};
8934649Swollman#define	SIOCSETVLAN	SIOCSIFGENERIC
9034649Swollman#define	SIOCGETVLAN	SIOCGIFGENERIC
9134649Swollman
92106932Ssam#ifdef _KERNEL
93106932Ssam/*
94106932Ssam * Drivers that are capable of adding and removing the VLAN header
95106932Ssam * in hardware indicate they support this by marking IFCAP_VLAN_HWTAGGING
96124683Syar * in if_capabilities.  Drivers for hardware that is capable
97106932Ssam * of handling larger MTU's that may include a software-appended
98124683Syar * VLAN header w/o lowering the normal MTU should mark IFCAP_VLAN_MTU
99124683Syar * in if_capabilities; this notifies the VLAN code it can leave the
100106932Ssam * MTU on the vlan interface at the normal setting.
101106932Ssam */
102106932Ssam
103106932Ssam/*
104162375Sandre * VLAN tags are stored in host byte order.  Byte swapping may be
105162375Sandre * necessary.
106106932Ssam *
107162375Sandre * Drivers that support hardware VLAN tag stripping fill in the
108162375Sandre * received VLAN tag (containing both vlan and priority information)
109162375Sandre * into the ether_vtag mbuf packet header field:
110162375Sandre *
111230026Srwatson *	m->m_pkthdr.ether_vtag = vtag;		// ntohs()?
112162375Sandre *	m->m_flags |= M_VLANTAG;
113106932Ssam *
114162375Sandre * to mark the packet m with the specified VLAN tag.
115106932Ssam *
116162375Sandre * On output the driver should check the mbuf for the M_VLANTAG
117162375Sandre * flag to see if a VLAN tag is present and valid:
118162375Sandre *
119162375Sandre *	if (m->m_flags & M_VLANTAG) {
120162375Sandre *		... = m->m_pkthdr.ether_vtag;	// htons()?
121106932Ssam *		... pass tag to hardware ...
122106932Ssam *	}
123106932Ssam *
124106932Ssam * Note that a driver must indicate it supports hardware VLAN
125162375Sandre * stripping/insertion by marking IFCAP_VLAN_HWTAGGING in
126162375Sandre * if_capabilities.
127106932Ssam */
128106932Ssam
129155051Sglebius#define	VLAN_CAPABILITIES(_ifp) do {				\
130155051Sglebius	if ((_ifp)->if_vlantrunk != NULL) 			\
131155051Sglebius		(*vlan_trunk_cap_p)(_ifp);			\
132155051Sglebius} while (0)
133155051Sglebius
134219819Sjeff#define	VLAN_TRUNKDEV(_ifp)					\
135219819Sjeff	(_ifp)->if_type == IFT_L2VLAN ? (*vlan_trunkdev_p)((_ifp)) : NULL
136230026Srwatson#define	VLAN_TAG(_ifp, _vid)					\
137230026Srwatson	(_ifp)->if_type == IFT_L2VLAN ? (*vlan_tag_p)((_ifp), (_vid)) : EINVAL
138219819Sjeff#define	VLAN_COOKIE(_ifp)					\
139219819Sjeff	(_ifp)->if_type == IFT_L2VLAN ? (*vlan_cookie_p)((_ifp)) : NULL
140219819Sjeff#define	VLAN_SETCOOKIE(_ifp, _cookie)				\
141219819Sjeff	(_ifp)->if_type == IFT_L2VLAN ?				\
142219819Sjeff	    (*vlan_setcookie_p)((_ifp), (_cookie)) : EINVAL
143230026Srwatson#define	VLAN_DEVAT(_ifp, _vid)					\
144230026Srwatson	(_ifp)->if_vlantrunk != NULL ? (*vlan_devat_p)((_ifp), (_vid)) : NULL
145219819Sjeff
146155051Sglebiusextern	void (*vlan_trunk_cap_p)(struct ifnet *);
147219819Sjeffextern	struct ifnet *(*vlan_trunkdev_p)(struct ifnet *);
148219819Sjeffextern	struct ifnet *(*vlan_devat_p)(struct ifnet *, uint16_t);
149219819Sjeffextern	int (*vlan_tag_p)(struct ifnet *, uint16_t *);
150219819Sjeffextern	int (*vlan_setcookie_p)(struct ifnet *, void *);
151219819Sjeffextern	void *(*vlan_cookie_p)(struct ifnet *);
152219819Sjeff
153106932Ssam#endif /* _KERNEL */
154106932Ssam
15534649Swollman#endif /* _NET_IF_VLAN_VAR_H_ */
156