1/*	$OpenBSD: if_trunk.h,v 1.31 2024/05/13 01:15:53 jsg Exp $	*/
2
3/*
4 * Copyright (c) 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef _NET_TRUNK_H
20#define _NET_TRUNK_H
21
22/*
23 * Global definitions
24 */
25
26#define TRUNK_MAX_PORTS		32	/* logically */
27#define TRUNK_MAX_NAMESIZE	32	/* name of a protocol */
28#define TRUNK_MAX_STACKING	4	/* maximum number of stacked trunks */
29
30/* Port flags */
31#define TRUNK_PORT_SLAVE		0x00000000 /* normal enslaved port */
32#define TRUNK_PORT_MASTER		0x00000001 /* primary port */
33#define TRUNK_PORT_STACK		0x00000002 /* stacked trunk port */
34#define TRUNK_PORT_ACTIVE		0x00000004 /* port is active */
35#define TRUNK_PORT_COLLECTING		0x00000008 /* port is receiving frames */
36#define TRUNK_PORT_DISTRIBUTING	0x00000010 /* port is sending frames */
37#define TRUNK_PORT_DISABLED		0x00000020 /* port is disabled */
38#define TRUNK_PORT_GLOBAL		0x80000000 /* IOCTL: global flag */
39#define TRUNK_PORT_BITS		"\20\01MASTER\02STACK\03ACTIVE" \
40					 "\04COLLECTING\05DISTRIBUTING\06DISABLED"
41
42/* Supported trunk PROTOs */
43enum trunk_proto {
44	TRUNK_PROTO_NONE	= 0,		/* no trunk protocol defined */
45	TRUNK_PROTO_ROUNDROBIN	= 1,		/* simple round robin */
46	TRUNK_PROTO_FAILOVER	= 2,		/* active failover */
47	TRUNK_PROTO_LOADBALANCE	= 3,		/* loadbalance */
48	TRUNK_PROTO_BROADCAST	= 4,		/* broadcast */
49	TRUNK_PROTO_LACP	= 5,		/* 802.3ad LACP */
50	TRUNK_PROTO_MAX		= 6
51};
52
53struct trunk_protos {
54	const char		*tpr_name;
55	enum trunk_proto	tpr_proto;
56};
57
58#define	TRUNK_PROTO_DEFAULT	TRUNK_PROTO_ROUNDROBIN
59#define TRUNK_PROTOS	{						\
60	{ "roundrobin",		TRUNK_PROTO_ROUNDROBIN },		\
61	{ "failover",		TRUNK_PROTO_FAILOVER },			\
62	{ "lacp",		TRUNK_PROTO_LACP },			\
63	{ "loadbalance",	TRUNK_PROTO_LOADBALANCE },		\
64	{ "broadcast",		TRUNK_PROTO_BROADCAST },		\
65	{ "none",		TRUNK_PROTO_NONE },			\
66	{ "default",		TRUNK_PROTO_DEFAULT }			\
67}
68
69/*
70 * Trunk ioctls.
71 */
72
73/*
74 * LACP current operational parameters structure.
75 */
76struct lacp_opreq {
77	u_int16_t		actor_prio;
78	u_int8_t		actor_mac[ETHER_ADDR_LEN];
79	u_int16_t		actor_key;
80	u_int16_t		actor_portprio;
81	u_int16_t		actor_portno;
82	u_int8_t		actor_state;
83	u_int16_t		partner_prio;
84	u_int8_t		partner_mac[ETHER_ADDR_LEN];
85	u_int16_t		partner_key;
86	u_int16_t		partner_portprio;
87	u_int16_t		partner_portno;
88	u_int8_t		partner_state;
89};
90
91/* Trunk port settings */
92struct trunk_reqport {
93	char			rp_ifname[IFNAMSIZ];	/* name of the trunk */
94	char			rp_portname[IFNAMSIZ];	/* name of the port */
95	u_int32_t		rp_prio;		/* port priority */
96	u_int32_t		rp_flags;		/* port flags */
97	union {
98		struct lacp_opreq rpsc_lacp;
99	} rp_psc;
100#define rp_lacpreq	rp_psc.rpsc_lacp
101};
102
103#define SIOCGTRUNKPORT		_IOWR('i', 140, struct trunk_reqport)
104#define SIOCSTRUNKPORT		 _IOW('i', 141, struct trunk_reqport)
105#define SIOCSTRUNKDELPORT	 _IOW('i', 142, struct trunk_reqport)
106
107/* Trunk, ports and options */
108struct trunk_reqall {
109	char			ra_ifname[IFNAMSIZ];	/* name of the trunk */
110	u_int			ra_proto;		/* trunk protocol */
111
112	size_t			ra_size;		/* size of buffer */
113	struct trunk_reqport	*ra_port;		/* allocated buffer */
114	int			ra_ports;		/* total port count */
115	union {
116		struct lacp_opreq rpsc_lacp;
117	} ra_psc;
118#define ra_lacpreq	ra_psc.rpsc_lacp
119};
120
121#define SIOCGTRUNK		_IOWR('i', 143, struct trunk_reqall)
122#define SIOCSTRUNK		 _IOW('i', 144, struct trunk_reqall)
123
124/* LACP administrative options */
125struct lacp_adminopts {
126	u_int8_t		lacp_mode;		/* active or passive */
127	u_int8_t		lacp_timeout;		/* fast or slow */
128	u_int16_t		lacp_prio;		/* system priority */
129	u_int16_t		lacp_portprio;		/* port priority */
130	u_int8_t		lacp_ifqprio;		/* ifq priority */
131};
132
133/* Trunk administrative options */
134struct trunk_opts {
135	char			to_ifname[IFNAMSIZ];	/* name of the trunk */
136	u_int			to_proto;		/* trunk protocol */
137	int			to_opts;		/* option bitmap */
138#define TRUNK_OPT_NONE			0x00
139#define TRUNK_OPT_LACP_MODE		0x01		/* set active bit */
140#define TRUNK_OPT_LACP_TIMEOUT		0x02		/* set timeout bit */
141#define TRUNK_OPT_LACP_SYS_PRIO		0x04		/* set sys_prio bit */
142#define TRUNK_OPT_LACP_PORT_PRIO	0x08		/* set port_prio bit */
143#define TRUNK_OPT_LACP_IFQ_PRIO		0x10		/* set ifq_prio bit */
144
145	union {
146		struct lacp_adminopts rpsc_lacp;
147	} to_psc;
148#define to_lacpopts	to_psc.rpsc_lacp
149};
150
151#define SIOCGTRUNKOPTS		_IOWR('i', 145, struct trunk_opts)
152#define SIOCSTRUNKOPTS		 _IOW('i', 146, struct trunk_opts)
153
154#ifdef _KERNEL
155/*
156 * Internal kernel part
157 */
158struct trunk_softc;
159struct trunk_port {
160	struct ifnet			*tp_if;		/* physical interface */
161	struct trunk_softc		*tp_trunk;	/* parent trunk */
162	u_int8_t			tp_lladdr[ETHER_ADDR_LEN];
163	caddr_t				tp_psc;		/* protocol data */
164
165	u_char				tp_iftype;	/* interface type */
166	u_int32_t			tp_prio;	/* port priority */
167	u_int32_t			tp_flags;	/* port flags */
168	struct task			tp_ltask;	/* if state hook */
169	struct task			tp_dtask;	/* if detach hook */
170
171	/* Redirected callbacks */
172	int	(*tp_ioctl)(struct ifnet *, u_long, caddr_t);
173	int	(*tp_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
174		    struct rtentry *);
175	void	(*tp_input)(struct ifnet *, struct mbuf *);
176
177	SLIST_ENTRY(trunk_port)		tp_entries;
178};
179
180#define tp_ifname		tp_if->if_xname		/* interface name */
181#define tp_ifflags		tp_if->if_flags		/* interface flags */
182#define tp_link_state		tp_if->if_link_state	/* link state */
183#define tp_capabilities		tp_if->if_capabilities	/* capabilities */
184
185#define TRUNK_PORTACTIVE(_tp)	(					\
186	LINK_STATE_IS_UP((_tp)->tp_link_state) &&			\
187	(_tp)->tp_ifflags & IFF_UP)
188
189struct trunk_mc {
190	union {
191		struct ether_multi	*mcu_enm;
192	} mc_u;
193	struct sockaddr_storage		mc_addr;
194
195	SLIST_ENTRY(trunk_mc)		mc_entries;
196};
197
198#define mc_enm	mc_u.mcu_enm
199
200struct trunk_ifreq {
201	union {
202		struct ifreq ifreq;
203		struct {
204			char ifr_name[IFNAMSIZ];
205			struct sockaddr_storage ifr_ss;
206		} ifreq_storage;
207	} ifreq;
208};
209
210struct trunk_softc {
211	struct arpcom			tr_ac;		/* virtual interface */
212	enum trunk_proto		tr_proto;	/* trunk protocol */
213	u_int				tr_count;	/* number of ports */
214	struct trunk_port		*tr_primary;	/* primary port */
215	struct ifmedia			tr_media;	/* media config */
216	caddr_t				tr_psc;		/* protocol data */
217
218	SLIST_HEAD(__tplhd, trunk_port)	tr_ports;	/* list of interfaces */
219	SLIST_ENTRY(trunk_softc)	tr_entries;
220
221	SLIST_HEAD(__mclhd, trunk_mc)	tr_mc_head;	/* multicast addresses */
222
223	/* Trunk protocol callbacks */
224	int	(*tr_detach)(struct trunk_softc *);
225	int	(*tr_start)(struct trunk_softc *, struct mbuf *);
226	int	(*tr_input)(struct trunk_softc *, struct trunk_port *,
227		    struct mbuf *);
228	int	(*tr_port_create)(struct trunk_port *);
229	void	(*tr_port_destroy)(struct trunk_port *);
230	void	(*tr_linkstate)(struct trunk_port *);
231	void	(*tr_init)(struct trunk_softc *);
232	void	(*tr_stop)(struct trunk_softc *);
233	void	(*tr_req)(struct trunk_softc *, caddr_t);
234	void	(*tr_portreq)(struct trunk_port *, caddr_t);
235};
236
237#define tr_ifflags		tr_ac.ac_if.if_flags		/* flags */
238#define tr_ifname		tr_ac.ac_if.if_xname		/* name */
239#define tr_capabilities		tr_ac.ac_if.if_capabilities	/* capabilities */
240#define tr_ifindex		tr_ac.ac_if.if_index		/* int index */
241#define tr_lladdr		tr_ac.ac_enaddr			/* lladdr */
242
243#define IFCAP_TRUNK_MASK	0xffff0000	/* private capabilities */
244#define IFCAP_TRUNK_FULLDUPLEX	0x00010000	/* full duplex with >1 ports */
245
246/* Private data used by the loadbalancing protocol */
247struct trunk_lb {
248	SIPHASH_KEY		lb_key;
249	struct trunk_port	*lb_ports[TRUNK_MAX_PORTS];
250};
251
252u_int32_t	trunk_hashmbuf(struct mbuf *, SIPHASH_KEY *);
253#endif /* _KERNEL */
254
255#endif /* _NET_TRUNK_H */
256