xref: /openbsd/sys/net/if_bridge.h (revision 3d8817e4)
1 /*	$OpenBSD: if_bridge.h,v 1.34 2010/11/20 14:23:09 fgsch Exp $	*/
2 
3 /*
4  * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
5  * Copyright (c) 2006 Andrew Thompson (thompsa@FreeBSD.org)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Effort sponsored in part by the Defense Advanced Research Projects
30  * Agency (DARPA) and Air Force Research Laboratory, Air Force
31  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
32  *
33  */
34 
35 #ifndef _NET_IF_BRIDGE_H_
36 #define _NET_IF_BRIDGE_H_
37 
38 #include <net/pfvar.h>
39 
40 /*
41  * Bridge control request: add/delete member interfaces.
42  */
43 struct ifbreq {
44 	char		ifbr_name[IFNAMSIZ];	/* bridge ifs name */
45 	char		ifbr_ifsname[IFNAMSIZ];	/* member ifs name */
46 	u_int32_t	ifbr_ifsflags;		/* member ifs flags */
47 	u_int8_t	ifbr_portno;		/* member port number */
48 
49 	u_int8_t	ifbr_state;		/* member stp state */
50 	u_int8_t	ifbr_priority;		/* member stp priority */
51 	u_int32_t	ifbr_path_cost;		/* member stp path cost */
52 	u_int32_t	ifbr_stpflags;          /* member stp flags */
53 	u_int8_t	ifbr_proto;		/* member stp protocol */
54 	u_int8_t	ifbr_role;		/* member stp role */
55 	u_int32_t	ifbr_fwd_trans;		/* member stp fwd transitions */
56 	u_int64_t	ifbr_desg_bridge;	/* member stp designated bridge */
57 	u_int32_t	ifbr_desg_port;		/* member stp designated port */
58 	u_int64_t	ifbr_root_bridge;	/* member stp root bridge */
59 	u_int32_t	ifbr_root_cost;		/* member stp root cost */
60 	u_int32_t	ifbr_root_port;		/* member stp root port */
61 };
62 
63 /* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */
64 #define	IFBIF_LEARNING		0x0001	/* ifs can learn */
65 #define	IFBIF_DISCOVER		0x0002	/* ifs sends packets w/unknown dest */
66 #define	IFBIF_BLOCKNONIP	0x0004	/* ifs blocks non-IP/ARP in/out */
67 #define	IFBIF_STP		0x0008	/* ifs participates in spanning tree */
68 #define IFBIF_BSTP_EDGE		0x0010	/* member stp edge port */
69 #define IFBIF_BSTP_AUTOEDGE	0x0020  /* member stp autoedge enabled */
70 #define IFBIF_BSTP_PTP		0x0040  /* member stp ptp */
71 #define IFBIF_BSTP_AUTOPTP	0x0080	/* member stp autoptp enabled */
72 #define	IFBIF_SPAN		0x0100	/* ifs is a span port (ro) */
73 #define	IFBIF_RO_MASK		0xff00	/* read only bits */
74 
75 /* SIOCBRDGFLUSH */
76 #define	IFBF_FLUSHDYN	0x0	/* flush dynamic addresses only */
77 #define	IFBF_FLUSHALL	0x1	/* flush all addresses from cache */
78 
79 /* port states */
80 #define	BSTP_IFSTATE_DISABLED	0
81 #define	BSTP_IFSTATE_LISTENING	1
82 #define	BSTP_IFSTATE_LEARNING	2
83 #define	BSTP_IFSTATE_FORWARDING	3
84 #define	BSTP_IFSTATE_BLOCKING	4
85 #define	BSTP_IFSTATE_DISCARDING	5
86 
87 #define	BSTP_TCSTATE_ACTIVE	1
88 #define	BSTP_TCSTATE_DETECTED	2
89 #define	BSTP_TCSTATE_INACTIVE	3
90 #define	BSTP_TCSTATE_LEARNING	4
91 #define	BSTP_TCSTATE_PROPAG	5
92 #define	BSTP_TCSTATE_ACK	6
93 #define	BSTP_TCSTATE_TC		7
94 #define	BSTP_TCSTATE_TCN	8
95 
96 #define	BSTP_ROLE_DISABLED	0
97 #define	BSTP_ROLE_ROOT		1
98 #define	BSTP_ROLE_DESIGNATED	2
99 #define	BSTP_ROLE_ALTERNATE	3
100 #define	BSTP_ROLE_BACKUP	4
101 
102 /*
103  * Interface list structure
104  */
105 struct ifbifconf {
106 	char		ifbic_name[IFNAMSIZ];	/* bridge ifs name */
107 	u_int32_t	ifbic_len;		/* buffer size */
108 	union {
109 		caddr_t	ifbicu_buf;
110 		struct	ifbreq *ifbicu_req;
111 	} ifbic_ifbicu;
112 #define	ifbic_buf	ifbic_ifbicu.ifbicu_buf
113 #define	ifbic_req	ifbic_ifbicu.ifbicu_req
114 };
115 
116 /*
117  * Bridge address request
118  */
119 struct ifbareq {
120 	char			ifba_name[IFNAMSIZ];	/* bridge name */
121 	char			ifba_ifsname[IFNAMSIZ];	/* destination ifs */
122 	u_int8_t		ifba_age;		/* address age */
123 	u_int8_t		ifba_flags;		/* address flags */
124 	struct ether_addr	ifba_dst;		/* destination addr */
125 };
126 
127 #define	IFBAF_TYPEMASK		0x03		/* address type mask */
128 #define	IFBAF_DYNAMIC		0x00		/* dynamically learned */
129 #define	IFBAF_STATIC		0x01		/* static address */
130 
131 struct ifbaconf {
132 	char			ifbac_name[IFNAMSIZ];	/* bridge ifs name */
133 	u_int32_t		ifbac_len;		/* buffer size */
134 	union {
135 		caddr_t	ifbacu_buf;			/* buffer */
136 		struct ifbareq *ifbacu_req;		/* request pointer */
137 	} ifbac_ifbacu;
138 #define	ifbac_buf	ifbac_ifbacu.ifbacu_buf
139 #define	ifbac_req	ifbac_ifbacu.ifbacu_req
140 };
141 
142 struct ifbrparam {
143 	char			ifbrp_name[IFNAMSIZ];
144 	union {
145 		u_int32_t	ifbrpu_csize;		/* cache size */
146 		int		ifbrpu_ctime;		/* cache time (sec) */
147 		u_int16_t	ifbrpu_prio;		/* bridge priority */
148 		u_int8_t	ifbrpu_hellotime;	/* hello time (sec) */
149 		u_int8_t	ifbrpu_fwddelay;	/* fwd delay (sec) */
150 		u_int8_t	ifbrpu_maxage;		/* max age (sec) */
151 		u_int8_t	ifbrpu_proto;		/* bridge protocol */
152 		u_int8_t	ifbrpu_txhc;		/* bpdu tx holdcount */
153 	} ifbrp_ifbrpu;
154 };
155 #define	ifbrp_csize	ifbrp_ifbrpu.ifbrpu_csize
156 #define	ifbrp_ctime	ifbrp_ifbrpu.ifbrpu_ctime
157 #define	ifbrp_prio	ifbrp_ifbrpu.ifbrpu_prio
158 #define	ifbrp_proto	ifbrp_ifbrpu.ifbrpu_proto
159 #define	ifbrp_txhc	ifbrp_ifbrpu.ifbrpu_txhc
160 #define	ifbrp_hellotime	ifbrp_ifbrpu.ifbrpu_hellotime
161 #define	ifbrp_fwddelay	ifbrp_ifbrpu.ifbrpu_fwddelay
162 #define	ifbrp_maxage	ifbrp_ifbrpu.ifbrpu_maxage
163 
164 /* Protocol versions */
165 #define	BSTP_PROTO_ID		0x00
166 #define	BSTP_PROTO_STP		0x00
167 #define	BSTP_PROTO_RSTP		0x02
168 #define	BSTP_PROTO_MAX		BSTP_PROTO_RSTP
169 
170 /*
171  * Bridge current operational parameters structure.
172  */
173 struct ifbropreq {
174 	char		ifbop_name[IFNAMSIZ];
175 	u_int8_t	ifbop_holdcount;
176 	u_int8_t	ifbop_maxage;
177 	u_int8_t	ifbop_hellotime;
178 	u_int8_t	ifbop_fwddelay;
179 	u_int8_t	ifbop_protocol;
180 	u_int16_t	ifbop_priority;
181 	u_int64_t	ifbop_root_bridge;
182 	u_int16_t	ifbop_root_port;
183 	u_int32_t	ifbop_root_path_cost;
184 	u_int64_t	ifbop_desg_bridge;
185 	struct timeval	ifbop_last_tc_time;
186 };
187 
188 /*
189  * Bridge mac rules
190  */
191 struct ifbrlreq {
192 	char			ifbr_name[IFNAMSIZ];	/* bridge ifs name */
193 	char			ifbr_ifsname[IFNAMSIZ];	/* member ifs name */
194 	u_int8_t		ifbr_action;		/* disposition */
195 	u_int8_t		ifbr_flags;		/* flags */
196 	struct ether_addr	ifbr_src;		/* source mac */
197 	struct ether_addr	ifbr_dst;		/* destination mac */
198 	char			ifbr_tagname[PF_TAG_NAME_SIZE];	/* pf tagname */
199 };
200 #define	BRL_ACTION_BLOCK	0x01			/* block frame */
201 #define	BRL_ACTION_PASS		0x02			/* pass frame */
202 #define	BRL_FLAG_IN		0x08			/* input rule */
203 #define	BRL_FLAG_OUT		0x04			/* output rule */
204 #define	BRL_FLAG_SRCVALID	0x02			/* src valid */
205 #define	BRL_FLAG_DSTVALID	0x01			/* dst valid */
206 
207 struct ifbrlconf {
208 	char		ifbrl_name[IFNAMSIZ];	/* bridge ifs name */
209 	char		ifbrl_ifsname[IFNAMSIZ];/* member ifs name */
210 	u_int32_t	ifbrl_len;		/* buffer size */
211 	union {
212 		caddr_t	ifbrlu_buf;
213 		struct	ifbrlreq *ifbrlu_req;
214 	} ifbrl_ifbrlu;
215 #define	ifbrl_buf	ifbrl_ifbrlu.ifbrlu_buf
216 #define	ifbrl_req	ifbrl_ifbrlu.ifbrlu_req
217 };
218 
219 #ifdef _KERNEL
220 /* STP port flags */
221 #define	BSTP_PORT_CANMIGRATE	0x0001
222 #define	BSTP_PORT_NEWINFO	0x0002
223 #define	BSTP_PORT_DISPUTED	0x0004
224 #define	BSTP_PORT_ADMCOST	0x0008
225 #define	BSTP_PORT_AUTOEDGE	0x0010
226 #define	BSTP_PORT_AUTOPTP	0x0020
227 
228 /* BPDU priority */
229 #define	BSTP_PDU_SUPERIOR	1
230 #define	BSTP_PDU_REPEATED	2
231 #define	BSTP_PDU_INFERIOR	3
232 #define	BSTP_PDU_INFERIORALT	4
233 #define	BSTP_PDU_OTHER		5
234 
235 /* BPDU flags */
236 #define	BSTP_PDU_PRMASK		0x0c		/* Port Role */
237 #define	BSTP_PDU_PRSHIFT	2		/* Port Role offset */
238 #define	BSTP_PDU_F_UNKN		0x00		/* Unknown port    (00) */
239 #define	BSTP_PDU_F_ALT		0x01		/* Alt/Backup port (01) */
240 #define	BSTP_PDU_F_ROOT		0x02		/* Root port       (10) */
241 #define	BSTP_PDU_F_DESG		0x03		/* Designated port (11) */
242 
243 #define	BSTP_PDU_STPMASK	0x81		/* strip unused STP flags */
244 #define	BSTP_PDU_RSTPMASK	0x7f		/* strip unused RSTP flags */
245 #define	BSTP_PDU_F_TC		0x01		/* Topology change */
246 #define	BSTP_PDU_F_P		0x02		/* Proposal flag */
247 #define	BSTP_PDU_F_L		0x10		/* Learning flag */
248 #define	BSTP_PDU_F_F		0x20		/* Forwarding flag */
249 #define	BSTP_PDU_F_A		0x40		/* Agreement flag */
250 #define	BSTP_PDU_F_TCA		0x80		/* Topology change ack */
251 
252 /*
253  * Bridge filtering rules
254  */
255 SIMPLEQ_HEAD(brl_head, brl_node);
256 
257 struct brl_node {
258 	SIMPLEQ_ENTRY(brl_node)	brl_next;	/* next rule */
259 	struct ether_addr	brl_src;	/* source mac address */
260 	struct ether_addr	brl_dst;	/* destination mac address */
261 	u_int16_t		brl_tag;	/* pf tag ID */
262 	u_int8_t		brl_action;	/* what to do with match */
263 	u_int8_t		brl_flags;	/* comparision flags */
264 };
265 
266 struct bstp_timer {
267 	u_int16_t	active;
268 	u_int16_t	value;
269 	u_int32_t	latched;
270 };
271 
272 struct bstp_pri_vector {
273 	u_int64_t	pv_root_id;
274 	u_int32_t	pv_cost;
275 	u_int64_t	pv_dbridge_id;
276 	u_int16_t	pv_dport_id;
277 	u_int16_t	pv_port_id;
278 };
279 
280 struct bstp_config_unit {
281 	struct bstp_pri_vector	cu_pv;
282 	u_int16_t	cu_message_age;
283 	u_int16_t	cu_max_age;
284 	u_int16_t	cu_forward_delay;
285 	u_int16_t	cu_hello_time;
286 	u_int8_t	cu_message_type;
287 	u_int8_t	cu_topology_change_ack;
288 	u_int8_t	cu_topology_change;
289 	u_int8_t	cu_proposal;
290 	u_int8_t	cu_agree;
291 	u_int8_t	cu_learning;
292 	u_int8_t	cu_forwarding;
293 	u_int8_t	cu_role;
294 };
295 
296 struct bstp_tcn_unit {
297 	u_int8_t	tu_message_type;
298 };
299 
300 struct bstp_port {
301 	LIST_ENTRY(bstp_port)	bp_next;
302 	struct ifnet		*bp_ifp;	/* parent if */
303 	struct bstp_state	*bp_bs;
304 	void			*bp_lhcookie;	/* if linkstate hook */
305 	u_int8_t		bp_active;
306 	u_int8_t		bp_protover;
307 	u_int32_t		bp_flags;
308 	u_int32_t		bp_path_cost;
309 	u_int16_t		bp_port_msg_age;
310 	u_int16_t		bp_port_max_age;
311 	u_int16_t		bp_port_fdelay;
312 	u_int16_t		bp_port_htime;
313 	u_int16_t		bp_desg_msg_age;
314 	u_int16_t		bp_desg_max_age;
315 	u_int16_t		bp_desg_fdelay;
316 	u_int16_t		bp_desg_htime;
317 	struct bstp_timer	bp_edge_delay_timer;
318 	struct bstp_timer	bp_forward_delay_timer;
319 	struct bstp_timer	bp_hello_timer;
320 	struct bstp_timer	bp_message_age_timer;
321 	struct bstp_timer	bp_migrate_delay_timer;
322 	struct bstp_timer	bp_recent_backup_timer;
323 	struct bstp_timer	bp_recent_root_timer;
324 	struct bstp_timer	bp_tc_timer;
325 	struct bstp_config_unit bp_msg_cu;
326 	struct bstp_pri_vector	bp_desg_pv;
327 	struct bstp_pri_vector	bp_port_pv;
328 	u_int16_t		bp_port_id;
329 	u_int8_t		bp_state;
330 	u_int8_t		bp_tcstate;
331 	u_int8_t		bp_role;
332 	u_int8_t		bp_infois;
333 	u_int8_t		bp_tc_ack;
334 	u_int8_t		bp_tc_prop;
335 	u_int8_t		bp_fdbflush;
336 	u_int8_t		bp_priority;
337 	u_int8_t		bp_ptp_link;
338 	u_int8_t		bp_agree;
339 	u_int8_t		bp_agreed;
340 	u_int8_t		bp_sync;
341 	u_int8_t		bp_synced;
342 	u_int8_t		bp_proposing;
343 	u_int8_t		bp_proposed;
344 	u_int8_t		bp_operedge;
345 	u_int8_t		bp_reroot;
346 	u_int8_t		bp_rcvdtc;
347 	u_int8_t		bp_rcvdtca;
348 	u_int8_t		bp_rcvdtcn;
349 	u_int32_t		bp_forward_transitions;
350 	u_int8_t		bp_txcount;
351 };
352 
353 /*
354  * Software state for each bridge STP.
355  */
356 struct bstp_state {
357 	struct ifnet		*bs_ifp;
358 	struct bstp_pri_vector	bs_bridge_pv;
359 	struct bstp_pri_vector	bs_root_pv;
360 	struct bstp_port	*bs_root_port;
361 	u_int8_t		bs_protover;
362 	u_int16_t		bs_migration_delay;
363 	u_int16_t		bs_edge_delay;
364 	u_int16_t		bs_bridge_max_age;
365 	u_int16_t		bs_bridge_fdelay;
366 	u_int16_t		bs_bridge_htime;
367 	u_int16_t		bs_root_msg_age;
368 	u_int16_t		bs_root_max_age;
369 	u_int16_t		bs_root_fdelay;
370 	u_int16_t		bs_root_htime;
371 	u_int16_t		bs_hold_time;
372 	u_int16_t		bs_bridge_priority;
373 	u_int8_t		bs_txholdcount;
374 	u_int8_t		bs_allsynced;
375 	struct timeout		bs_bstptimeout;		/* stp timeout */
376 	struct bstp_timer	bs_link_timer;
377 	struct timeval		bs_last_tc_time;
378 	LIST_HEAD(, bstp_port)	bs_bplist;
379 };
380 #define	bs_ifflags		bs_ifp->if_flags
381 
382 /*
383  * Bridge interface list
384  */
385 struct bridge_iflist {
386 	LIST_ENTRY(bridge_iflist)	next;		/* next in list */
387 	struct bstp_port		*bif_stp;	/* STP port state */
388 	struct brl_head			bif_brlin;	/* input rules */
389 	struct brl_head			bif_brlout;	/* output rules */
390 	struct				ifnet *ifp;	/* member interface */
391 	u_int32_t			bif_flags;	/* member flags */
392 };
393 #define bif_state			bif_stp->bp_state
394 
395 /*
396  * Bridge route node
397  */
398 struct bridge_rtnode {
399 	LIST_ENTRY(bridge_rtnode)	brt_next;	/* next in list */
400 	struct				ifnet *brt_if;	/* destination ifs */
401 	u_int8_t			brt_flags;	/* address flags */
402 	u_int8_t			brt_age;	/* age counter */
403 	struct				ether_addr brt_addr;	/* dst addr */
404 };
405 
406 #ifndef BRIDGE_RTABLE_SIZE
407 #define BRIDGE_RTABLE_SIZE	1024
408 #endif
409 #define BRIDGE_RTABLE_MASK	(BRIDGE_RTABLE_SIZE - 1)
410 
411 /*
412  * Software state for each bridge
413  */
414 struct bridge_softc {
415 	struct ifnet			sc_if;	/* the interface */
416 	LIST_ENTRY(bridge_softc)	sc_list;	/* all bridges */
417 	struct bridge_iflist		*sc_root_port;
418 	u_int32_t			sc_brtmax;	/* max # addresses */
419 	u_int32_t			sc_brtcnt;	/* current # addrs */
420 	int				sc_brttimeout;	/* timeout ticks */
421 	u_int32_t			sc_hashkey;	/* hash key */
422 	struct timeout			sc_brtimeout;	/* timeout state */
423 	struct bstp_state		*sc_stp;	/* stp state */
424 	LIST_HEAD(, bridge_iflist)	sc_iflist;	/* interface list */
425 	LIST_HEAD(, bridge_rtnode)	sc_rts[BRIDGE_RTABLE_SIZE];	/* hash table */
426 	LIST_HEAD(, bridge_iflist)	sc_spanlist;	/* span ports */
427 };
428 
429 extern const u_int8_t bstp_etheraddr[];
430 
431 void	bridge_ifdetach(struct ifnet *);
432 struct mbuf *bridge_input(struct ifnet *, struct ether_header *,
433     struct mbuf *);
434 int	bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
435     struct rtentry *);
436 void	bridge_update(struct ifnet *, struct ether_addr *, int);
437 void	bridge_rtdelete(struct bridge_softc *, struct ifnet *, int);
438 void	bridge_rtagenode(struct ifnet *, int);
439 
440 struct bstp_state *bstp_create(struct ifnet *);
441 void	bstp_destroy(struct bstp_state *);
442 void	bstp_initialization(struct bstp_state *);
443 void	bstp_stop(struct bstp_state *);
444 int	bstp_ioctl(struct ifnet *, u_long, caddr_t);
445 struct bstp_port *bstp_add(struct bstp_state *, struct ifnet *);
446 void	bstp_delete(struct bstp_port *);
447 void	bstp_input(struct bstp_state *, struct bstp_port *,
448     struct ether_header *, struct mbuf *);
449 void	bstp_ifstate(void *);
450 u_int8_t bstp_getstate(struct bstp_state *, struct bstp_port *);
451 void	bstp_ifsflags(struct bstp_port *, u_int);
452 #endif /* _KERNEL */
453 #endif /* _NET_IF_BRIDGE_H_ */
454