xref: /openbsd-src/sys/net/if_bridge.h (revision 9f9935a8e959ae3912357f67f4fed13f93d4ba9b)
1*9f9935a8Sclaudio /*	$OpenBSD: if_bridge.h,v 1.73 2021/11/11 10:03:10 claudio Exp $	*/
2d4773ae9Sjason 
3d4773ae9Sjason /*
4a475b322Sjason  * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
5b1b9d014Sreyk  * Copyright (c) 2006 Andrew Thompson (thompsa@FreeBSD.org)
6d4773ae9Sjason  * All rights reserved.
7d4773ae9Sjason  *
8d4773ae9Sjason  * Redistribution and use in source and binary forms, with or without
9d4773ae9Sjason  * modification, are permitted provided that the following conditions
10d4773ae9Sjason  * are met:
11d4773ae9Sjason  * 1. Redistributions of source code must retain the above copyright
12d4773ae9Sjason  *    notice, this list of conditions and the following disclaimer.
13d4773ae9Sjason  * 2. Redistributions in binary form must reproduce the above copyright
14d4773ae9Sjason  *    notice, this list of conditions and the following disclaimer in the
15d4773ae9Sjason  *    documentation and/or other materials provided with the distribution.
16d4773ae9Sjason  *
17d4773ae9Sjason  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18d4773ae9Sjason  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19d4773ae9Sjason  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20d4773ae9Sjason  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21d4773ae9Sjason  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22d4773ae9Sjason  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23d4773ae9Sjason  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24d4773ae9Sjason  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25d4773ae9Sjason  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26d4773ae9Sjason  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27d4773ae9Sjason  * POSSIBILITY OF SUCH DAMAGE.
285248d82bSjason  *
295248d82bSjason  * Effort sponsored in part by the Defense Advanced Research Projects
305248d82bSjason  * Agency (DARPA) and Air Force Research Laboratory, Air Force
315248d82bSjason  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
325248d82bSjason  *
33d4773ae9Sjason  */
34d4773ae9Sjason 
35e04c8cc2Sangelos #ifndef _NET_IF_BRIDGE_H_
36e04c8cc2Sangelos #define _NET_IF_BRIDGE_H_
37e04c8cc2Sangelos 
38282291edSmpi #include <sys/smr.h>
397348f865Sdlg #include <sys/timeout.h>
40c38b3436Shenning #include <net/pfvar.h>
41c38b3436Shenning 
42d4773ae9Sjason /*
43df03cbb0Sjason  * Bridge control request: add/delete member interfaces.
44d4773ae9Sjason  */
45d4773ae9Sjason struct ifbreq {
46df03cbb0Sjason 	char		ifbr_name[IFNAMSIZ];	/* bridge ifs name */
47df03cbb0Sjason 	char		ifbr_ifsname[IFNAMSIZ];	/* member ifs name */
485c2bf750Sjason 	u_int32_t	ifbr_ifsflags;		/* member ifs flags */
4970d427baSgoda 	u_int32_t	ifbr_portno;		/* member port number */
500a04437dSmpi 	u_int32_t	ifbr_protected;		/* protected domains */
51b1b9d014Sreyk 
529fa0b7aaSjason 	u_int8_t	ifbr_state;		/* member stp state */
539fa0b7aaSjason 	u_int8_t	ifbr_priority;		/* member stp priority */
54f24dd164Smarkus 	u_int32_t	ifbr_path_cost;		/* member stp path cost */
55b1b9d014Sreyk 	u_int32_t	ifbr_stpflags;          /* member stp flags */
56b1b9d014Sreyk 	u_int8_t	ifbr_proto;		/* member stp protocol */
57b1b9d014Sreyk 	u_int8_t	ifbr_role;		/* member stp role */
58b1b9d014Sreyk 	u_int32_t	ifbr_fwd_trans;		/* member stp fwd transitions */
59b1b9d014Sreyk 	u_int64_t	ifbr_desg_bridge;	/* member stp designated bridge */
60b1b9d014Sreyk 	u_int32_t	ifbr_desg_port;		/* member stp designated port */
61b1b9d014Sreyk 	u_int64_t	ifbr_root_bridge;	/* member stp root bridge */
62b1b9d014Sreyk 	u_int32_t	ifbr_root_cost;		/* member stp root cost */
63b1b9d014Sreyk 	u_int32_t	ifbr_root_port;		/* member stp root port */
64d4773ae9Sjason };
65b1b9d014Sreyk 
665c2bf750Sjason /* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */
674c7242f8Sjason #define	IFBIF_LEARNING		0x0001	/* ifs can learn */
684c7242f8Sjason #define	IFBIF_DISCOVER		0x0002	/* ifs sends packets w/unknown dest */
694c7242f8Sjason #define	IFBIF_BLOCKNONIP	0x0004	/* ifs blocks non-IP/ARP in/out */
704c7242f8Sjason #define	IFBIF_STP		0x0008	/* ifs participates in spanning tree */
71b1b9d014Sreyk #define IFBIF_BSTP_EDGE		0x0010	/* member stp edge port */
72b1b9d014Sreyk #define IFBIF_BSTP_AUTOEDGE	0x0020  /* member stp autoedge enabled */
73ff7746e3Sreyk #define IFBIF_BSTP_PTP		0x0040  /* member stp ptp */
74ff7746e3Sreyk #define IFBIF_BSTP_AUTOPTP	0x0080	/* member stp autoptp enabled */
754c7242f8Sjason #define	IFBIF_SPAN		0x0100	/* ifs is a span port (ro) */
7670d427baSgoda #define	IFBIF_LOCAL		0x1000	/* local port in switch(4) */
7770d427baSgoda #define	IFBIF_RO_MASK		0x0f00	/* read only bits */
78b1b9d014Sreyk 
795c2bf750Sjason /* SIOCBRDGFLUSH */
805c2bf750Sjason #define	IFBF_FLUSHDYN	0x0	/* flush dynamic addresses only */
815c2bf750Sjason #define	IFBF_FLUSHALL	0x1	/* flush all addresses from cache */
828136e896Sjason 
839fa0b7aaSjason /* port states */
849fa0b7aaSjason #define	BSTP_IFSTATE_DISABLED	0
859fa0b7aaSjason #define	BSTP_IFSTATE_LISTENING	1
869fa0b7aaSjason #define	BSTP_IFSTATE_LEARNING	2
879fa0b7aaSjason #define	BSTP_IFSTATE_FORWARDING	3
889fa0b7aaSjason #define	BSTP_IFSTATE_BLOCKING	4
89b1b9d014Sreyk #define	BSTP_IFSTATE_DISCARDING	5
90b1b9d014Sreyk 
91b1b9d014Sreyk #define	BSTP_TCSTATE_ACTIVE	1
92b1b9d014Sreyk #define	BSTP_TCSTATE_DETECTED	2
93b1b9d014Sreyk #define	BSTP_TCSTATE_INACTIVE	3
94b1b9d014Sreyk #define	BSTP_TCSTATE_LEARNING	4
95b1b9d014Sreyk #define	BSTP_TCSTATE_PROPAG	5
96b1b9d014Sreyk #define	BSTP_TCSTATE_ACK	6
97b1b9d014Sreyk #define	BSTP_TCSTATE_TC		7
98b1b9d014Sreyk #define	BSTP_TCSTATE_TCN	8
99b1b9d014Sreyk 
100b1b9d014Sreyk #define	BSTP_ROLE_DISABLED	0
101b1b9d014Sreyk #define	BSTP_ROLE_ROOT		1
102b1b9d014Sreyk #define	BSTP_ROLE_DESIGNATED	2
103b1b9d014Sreyk #define	BSTP_ROLE_ALTERNATE	3
104b1b9d014Sreyk #define	BSTP_ROLE_BACKUP	4
1059fa0b7aaSjason 
106d4773ae9Sjason /*
107df03cbb0Sjason  * Interface list structure
108d4773ae9Sjason  */
109df03cbb0Sjason struct ifbifconf {
110df03cbb0Sjason 	char		ifbic_name[IFNAMSIZ];	/* bridge ifs name */
111df03cbb0Sjason 	u_int32_t	ifbic_len;		/* buffer size */
112df03cbb0Sjason 	union {
113df03cbb0Sjason 		caddr_t	ifbicu_buf;
114df03cbb0Sjason 		struct	ifbreq *ifbicu_req;
115df03cbb0Sjason 	} ifbic_ifbicu;
116df03cbb0Sjason #define	ifbic_buf	ifbic_ifbicu.ifbicu_buf
117df03cbb0Sjason #define	ifbic_req	ifbic_ifbicu.ifbicu_req
118df03cbb0Sjason };
119df03cbb0Sjason 
120df03cbb0Sjason /*
121df03cbb0Sjason  * Bridge address request
122df03cbb0Sjason  */
123df03cbb0Sjason struct ifbareq {
124a236f563Sjason 	char			ifba_name[IFNAMSIZ];	/* bridge name */
125a236f563Sjason 	char			ifba_ifsname[IFNAMSIZ];	/* destination ifs */
126a236f563Sjason 	u_int8_t		ifba_age;		/* address age */
127a236f563Sjason 	u_int8_t		ifba_flags;		/* address flags */
128df03cbb0Sjason 	struct ether_addr	ifba_dst;		/* destination addr */
129d72e8ec4Sreyk 	struct sockaddr_storage	ifba_dstsa;		/* tunnel endpoint */
130df03cbb0Sjason };
131df03cbb0Sjason 
132a236f563Sjason #define	IFBAF_TYPEMASK		0x03		/* address type mask */
133a236f563Sjason #define	IFBAF_DYNAMIC		0x00		/* dynamically learned */
134a236f563Sjason #define	IFBAF_STATIC		0x01		/* static address */
135a236f563Sjason 
136df03cbb0Sjason struct ifbaconf {
137df03cbb0Sjason 	char			ifbac_name[IFNAMSIZ];	/* bridge ifs name */
138df03cbb0Sjason 	u_int32_t		ifbac_len;		/* buffer size */
139df03cbb0Sjason 	union {
140df03cbb0Sjason 		caddr_t	ifbacu_buf;			/* buffer */
141df03cbb0Sjason 		struct ifbareq *ifbacu_req;		/* request pointer */
142df03cbb0Sjason 	} ifbac_ifbacu;
143df03cbb0Sjason #define	ifbac_buf	ifbac_ifbacu.ifbacu_buf
144df03cbb0Sjason #define	ifbac_req	ifbac_ifbacu.ifbacu_req
145df03cbb0Sjason };
146df03cbb0Sjason 
1479fa0b7aaSjason struct ifbrparam {
1489fa0b7aaSjason 	char			ifbrp_name[IFNAMSIZ];
1499fa0b7aaSjason 	union {
1509fa0b7aaSjason 		u_int32_t	ifbrpu_csize;		/* cache size */
15199b6c6e1Shenning 		int		ifbrpu_ctime;		/* cache time (sec) */
1529fa0b7aaSjason 		u_int16_t	ifbrpu_prio;		/* bridge priority */
1539fa0b7aaSjason 		u_int8_t	ifbrpu_hellotime;	/* hello time (sec) */
1549fa0b7aaSjason 		u_int8_t	ifbrpu_fwddelay;	/* fwd delay (sec) */
1559fa0b7aaSjason 		u_int8_t	ifbrpu_maxage;		/* max age (sec) */
156b1b9d014Sreyk 		u_int8_t	ifbrpu_proto;		/* bridge protocol */
157b1b9d014Sreyk 		u_int8_t	ifbrpu_txhc;		/* bpdu tx holdcount */
1589fa0b7aaSjason 	} ifbrp_ifbrpu;
159d4773ae9Sjason };
1609fa0b7aaSjason #define	ifbrp_csize	ifbrp_ifbrpu.ifbrpu_csize
1619fa0b7aaSjason #define	ifbrp_ctime	ifbrp_ifbrpu.ifbrpu_ctime
1629fa0b7aaSjason #define	ifbrp_prio	ifbrp_ifbrpu.ifbrpu_prio
163b1b9d014Sreyk #define	ifbrp_proto	ifbrp_ifbrpu.ifbrpu_proto
164b1b9d014Sreyk #define	ifbrp_txhc	ifbrp_ifbrpu.ifbrpu_txhc
1659fa0b7aaSjason #define	ifbrp_hellotime	ifbrp_ifbrpu.ifbrpu_hellotime
1669fa0b7aaSjason #define	ifbrp_fwddelay	ifbrp_ifbrpu.ifbrpu_fwddelay
1679fa0b7aaSjason #define	ifbrp_maxage	ifbrp_ifbrpu.ifbrpu_maxage
1684c8cd6dbSjason 
169b1b9d014Sreyk /* Protocol versions */
170b1b9d014Sreyk #define	BSTP_PROTO_ID		0x00
171b1b9d014Sreyk #define	BSTP_PROTO_STP		0x00
172b1b9d014Sreyk #define	BSTP_PROTO_RSTP		0x02
173b1b9d014Sreyk #define	BSTP_PROTO_MAX		BSTP_PROTO_RSTP
174b1b9d014Sreyk 
175b1b9d014Sreyk /*
176b1b9d014Sreyk  * Bridge current operational parameters structure.
177b1b9d014Sreyk  */
178b1b9d014Sreyk struct ifbropreq {
179b1b9d014Sreyk 	char		ifbop_name[IFNAMSIZ];
180b1b9d014Sreyk 	u_int8_t	ifbop_holdcount;
181b1b9d014Sreyk 	u_int8_t	ifbop_maxage;
182b1b9d014Sreyk 	u_int8_t	ifbop_hellotime;
183b1b9d014Sreyk 	u_int8_t	ifbop_fwddelay;
184b1b9d014Sreyk 	u_int8_t	ifbop_protocol;
185b1b9d014Sreyk 	u_int16_t	ifbop_priority;
186b1b9d014Sreyk 	u_int64_t	ifbop_root_bridge;
187b1b9d014Sreyk 	u_int16_t	ifbop_root_port;
188b1b9d014Sreyk 	u_int32_t	ifbop_root_path_cost;
189b1b9d014Sreyk 	u_int64_t	ifbop_desg_bridge;
190b1b9d014Sreyk 	struct timeval	ifbop_last_tc_time;
191b1b9d014Sreyk };
192b1b9d014Sreyk 
193a475b322Sjason /*
194a475b322Sjason  * Bridge mac rules
195a475b322Sjason  */
196d6404d18Shenning struct ifbrarpf {
197d6404d18Shenning 	u_int16_t		brla_flags;
198d6404d18Shenning 	u_int16_t		brla_op;
199d6404d18Shenning 	struct ether_addr	brla_sha;
200d6404d18Shenning 	struct in_addr		brla_spa;
201d6404d18Shenning 	struct ether_addr	brla_tha;
202d6404d18Shenning 	struct in_addr		brla_tpa;
203d6404d18Shenning };
204d6404d18Shenning #define	BRLA_ARP	0x01
205d6404d18Shenning #define	BRLA_RARP	0x02
206d6404d18Shenning #define	BRLA_SHA	0x10
207d6404d18Shenning #define	BRLA_SPA	0x20
208d6404d18Shenning #define	BRLA_THA	0x40
209d6404d18Shenning #define	BRLA_TPA	0x80
210d6404d18Shenning 
211a475b322Sjason struct ifbrlreq {
212a475b322Sjason 	char			ifbr_name[IFNAMSIZ];	/* bridge ifs name */
213a475b322Sjason 	char			ifbr_ifsname[IFNAMSIZ];	/* member ifs name */
214a475b322Sjason 	u_int8_t		ifbr_action;		/* disposition */
215a475b322Sjason 	u_int8_t		ifbr_flags;		/* flags */
216a475b322Sjason 	struct ether_addr	ifbr_src;		/* source mac */
217a475b322Sjason 	struct ether_addr	ifbr_dst;		/* destination mac */
218c38b3436Shenning 	char			ifbr_tagname[PF_TAG_NAME_SIZE];	/* pf tagname */
219d6404d18Shenning 	struct ifbrarpf		ifbr_arpf;		/* arp filter */
220a475b322Sjason };
221a475b322Sjason #define	BRL_ACTION_BLOCK	0x01			/* block frame */
222a475b322Sjason #define	BRL_ACTION_PASS		0x02			/* pass frame */
223a475b322Sjason #define	BRL_FLAG_IN		0x08			/* input rule */
224a475b322Sjason #define	BRL_FLAG_OUT		0x04			/* output rule */
225a475b322Sjason #define	BRL_FLAG_SRCVALID	0x02			/* src valid */
226a475b322Sjason #define	BRL_FLAG_DSTVALID	0x01			/* dst valid */
227a475b322Sjason 
228a475b322Sjason struct ifbrlconf {
229a475b322Sjason 	char		ifbrl_name[IFNAMSIZ];	/* bridge ifs name */
230a475b322Sjason 	char		ifbrl_ifsname[IFNAMSIZ];/* member ifs name */
231a475b322Sjason 	u_int32_t	ifbrl_len;		/* buffer size */
232a475b322Sjason 	union {
233a475b322Sjason 		caddr_t	ifbrlu_buf;
234a475b322Sjason 		struct	ifbrlreq *ifbrlu_req;
235a475b322Sjason 	} ifbrl_ifbrlu;
236a475b322Sjason #define	ifbrl_buf	ifbrl_ifbrlu.ifbrlu_buf
237a475b322Sjason #define	ifbrl_req	ifbrl_ifbrlu.ifbrlu_req
238a475b322Sjason };
2394c8cd6dbSjason 
240d4773ae9Sjason #ifdef _KERNEL
24196d0f2aeSmpi 
24296d0f2aeSmpi #include <sys/mutex.h>
24396d0f2aeSmpi 
244b1b9d014Sreyk /* STP port flags */
245b1b9d014Sreyk #define	BSTP_PORT_CANMIGRATE	0x0001
246b1b9d014Sreyk #define	BSTP_PORT_NEWINFO	0x0002
247b1b9d014Sreyk #define	BSTP_PORT_DISPUTED	0x0004
248b1b9d014Sreyk #define	BSTP_PORT_ADMCOST	0x0008
249b1b9d014Sreyk #define	BSTP_PORT_AUTOEDGE	0x0010
250ff7746e3Sreyk #define	BSTP_PORT_AUTOPTP	0x0020
251b1b9d014Sreyk 
252b1b9d014Sreyk /* BPDU priority */
253b1b9d014Sreyk #define	BSTP_PDU_SUPERIOR	1
254b1b9d014Sreyk #define	BSTP_PDU_REPEATED	2
255b1b9d014Sreyk #define	BSTP_PDU_INFERIOR	3
256b1b9d014Sreyk #define	BSTP_PDU_INFERIORALT	4
257b1b9d014Sreyk #define	BSTP_PDU_OTHER		5
258b1b9d014Sreyk 
259b1b9d014Sreyk /* BPDU flags */
260b1b9d014Sreyk #define	BSTP_PDU_PRMASK		0x0c		/* Port Role */
261b1b9d014Sreyk #define	BSTP_PDU_PRSHIFT	2		/* Port Role offset */
262b1b9d014Sreyk #define	BSTP_PDU_F_UNKN		0x00		/* Unknown port    (00) */
263b1b9d014Sreyk #define	BSTP_PDU_F_ALT		0x01		/* Alt/Backup port (01) */
264b1b9d014Sreyk #define	BSTP_PDU_F_ROOT		0x02		/* Root port       (10) */
265b1b9d014Sreyk #define	BSTP_PDU_F_DESG		0x03		/* Designated port (11) */
266b1b9d014Sreyk 
267b1b9d014Sreyk #define	BSTP_PDU_STPMASK	0x81		/* strip unused STP flags */
268b1b9d014Sreyk #define	BSTP_PDU_RSTPMASK	0x7f		/* strip unused RSTP flags */
269b1b9d014Sreyk #define	BSTP_PDU_F_TC		0x01		/* Topology change */
270b1b9d014Sreyk #define	BSTP_PDU_F_P		0x02		/* Proposal flag */
271b1b9d014Sreyk #define	BSTP_PDU_F_L		0x10		/* Learning flag */
272b1b9d014Sreyk #define	BSTP_PDU_F_F		0x20		/* Forwarding flag */
273b1b9d014Sreyk #define	BSTP_PDU_F_A		0x40		/* Agreement flag */
274b1b9d014Sreyk #define	BSTP_PDU_F_TCA		0x80		/* Topology change ack */
275b1b9d014Sreyk 
2769fa0b7aaSjason /*
2779fa0b7aaSjason  * Bridge filtering rules
2789fa0b7aaSjason  */
2799fa0b7aaSjason SIMPLEQ_HEAD(brl_head, brl_node);
2809fa0b7aaSjason 
2819fa0b7aaSjason struct brl_node {
2829fa0b7aaSjason 	SIMPLEQ_ENTRY(brl_node)	brl_next;	/* next rule */
2839fa0b7aaSjason 	struct ether_addr	brl_src;	/* source mac address */
2849fa0b7aaSjason 	struct ether_addr	brl_dst;	/* destination mac address */
285c38b3436Shenning 	u_int16_t		brl_tag;	/* pf tag ID */
2869fa0b7aaSjason 	u_int8_t		brl_action;	/* what to do with match */
287678831beSjsg 	u_int8_t		brl_flags;	/* comparison flags */
288d6404d18Shenning 	struct ifbrarpf		brl_arpf;	/* arp filter */
2899fa0b7aaSjason };
2909fa0b7aaSjason 
291b1b9d014Sreyk struct bstp_timer {
2929fa0b7aaSjason 	u_int16_t	active;
2939fa0b7aaSjason 	u_int16_t	value;
294b1b9d014Sreyk 	u_int32_t	latched;
295b1b9d014Sreyk };
296b1b9d014Sreyk 
297b1b9d014Sreyk struct bstp_pri_vector {
298b1b9d014Sreyk 	u_int64_t	pv_root_id;
299b1b9d014Sreyk 	u_int32_t	pv_cost;
300b1b9d014Sreyk 	u_int64_t	pv_dbridge_id;
301b1b9d014Sreyk 	u_int16_t	pv_dport_id;
302b1b9d014Sreyk 	u_int16_t	pv_port_id;
3039fa0b7aaSjason };
3049fa0b7aaSjason 
3059fa0b7aaSjason struct bstp_config_unit {
306b1b9d014Sreyk 	struct bstp_pri_vector	cu_pv;
3079fa0b7aaSjason 	u_int16_t	cu_message_age;
3089fa0b7aaSjason 	u_int16_t	cu_max_age;
3099fa0b7aaSjason 	u_int16_t	cu_forward_delay;
310b1b9d014Sreyk 	u_int16_t	cu_hello_time;
3119fa0b7aaSjason 	u_int8_t	cu_message_type;
312b1b9d014Sreyk 	u_int8_t	cu_topology_change_ack;
3139fa0b7aaSjason 	u_int8_t	cu_topology_change;
314b1b9d014Sreyk 	u_int8_t	cu_proposal;
315b1b9d014Sreyk 	u_int8_t	cu_agree;
316b1b9d014Sreyk 	u_int8_t	cu_learning;
317b1b9d014Sreyk 	u_int8_t	cu_forwarding;
318b1b9d014Sreyk 	u_int8_t	cu_role;
3199fa0b7aaSjason };
3209fa0b7aaSjason 
3219fa0b7aaSjason struct bstp_tcn_unit {
3229fa0b7aaSjason 	u_int8_t	tu_message_type;
3239fa0b7aaSjason };
3249fa0b7aaSjason 
325b1b9d014Sreyk struct bstp_port {
326b1b9d014Sreyk 	LIST_ENTRY(bstp_port)	bp_next;
327f6fc373eSmvs 	unsigned int		bp_ifindex;	/* parent interface index */
328b1b9d014Sreyk 	struct bstp_state	*bp_bs;
3294f5e51a4Sdlg 	struct task		bp_ltask;	/* if linkstate hook */
330b1b9d014Sreyk 	u_int8_t		bp_active;
331b1b9d014Sreyk 	u_int8_t		bp_protover;
332b1b9d014Sreyk 	u_int32_t		bp_flags;
333b1b9d014Sreyk 	u_int32_t		bp_path_cost;
334b1b9d014Sreyk 	u_int16_t		bp_port_msg_age;
335b1b9d014Sreyk 	u_int16_t		bp_port_max_age;
336b1b9d014Sreyk 	u_int16_t		bp_port_fdelay;
337b1b9d014Sreyk 	u_int16_t		bp_port_htime;
338b1b9d014Sreyk 	u_int16_t		bp_desg_msg_age;
339b1b9d014Sreyk 	u_int16_t		bp_desg_max_age;
340b1b9d014Sreyk 	u_int16_t		bp_desg_fdelay;
341b1b9d014Sreyk 	u_int16_t		bp_desg_htime;
342b1b9d014Sreyk 	struct bstp_timer	bp_edge_delay_timer;
343b1b9d014Sreyk 	struct bstp_timer	bp_forward_delay_timer;
344b1b9d014Sreyk 	struct bstp_timer	bp_hello_timer;
345b1b9d014Sreyk 	struct bstp_timer	bp_message_age_timer;
346b1b9d014Sreyk 	struct bstp_timer	bp_migrate_delay_timer;
347b1b9d014Sreyk 	struct bstp_timer	bp_recent_backup_timer;
348b1b9d014Sreyk 	struct bstp_timer	bp_recent_root_timer;
349b1b9d014Sreyk 	struct bstp_timer	bp_tc_timer;
350b1b9d014Sreyk 	struct bstp_config_unit bp_msg_cu;
351b1b9d014Sreyk 	struct bstp_pri_vector	bp_desg_pv;
352b1b9d014Sreyk 	struct bstp_pri_vector	bp_port_pv;
353b1b9d014Sreyk 	u_int16_t		bp_port_id;
354b1b9d014Sreyk 	u_int8_t		bp_state;
355b1b9d014Sreyk 	u_int8_t		bp_tcstate;
356b1b9d014Sreyk 	u_int8_t		bp_role;
357b1b9d014Sreyk 	u_int8_t		bp_infois;
358b1b9d014Sreyk 	u_int8_t		bp_tc_ack;
359b1b9d014Sreyk 	u_int8_t		bp_tc_prop;
360b1b9d014Sreyk 	u_int8_t		bp_fdbflush;
361b1b9d014Sreyk 	u_int8_t		bp_priority;
362ff7746e3Sreyk 	u_int8_t		bp_ptp_link;
363b1b9d014Sreyk 	u_int8_t		bp_agree;
364b1b9d014Sreyk 	u_int8_t		bp_agreed;
365b1b9d014Sreyk 	u_int8_t		bp_sync;
366b1b9d014Sreyk 	u_int8_t		bp_synced;
367b1b9d014Sreyk 	u_int8_t		bp_proposing;
368b1b9d014Sreyk 	u_int8_t		bp_proposed;
369b1b9d014Sreyk 	u_int8_t		bp_operedge;
370b1b9d014Sreyk 	u_int8_t		bp_reroot;
371b1b9d014Sreyk 	u_int8_t		bp_rcvdtc;
372b1b9d014Sreyk 	u_int8_t		bp_rcvdtca;
373b1b9d014Sreyk 	u_int8_t		bp_rcvdtcn;
374b1b9d014Sreyk 	u_int32_t		bp_forward_transitions;
375b1b9d014Sreyk 	u_int8_t		bp_txcount;
376b1b9d014Sreyk };
377b1b9d014Sreyk 
378b1b9d014Sreyk /*
379b1b9d014Sreyk  * Software state for each bridge STP.
380b1b9d014Sreyk  */
381b1b9d014Sreyk struct bstp_state {
38213dba897Smvs 	unsigned int		bs_ifindex;
383b1b9d014Sreyk 	struct bstp_pri_vector	bs_bridge_pv;
384b1b9d014Sreyk 	struct bstp_pri_vector	bs_root_pv;
385b1b9d014Sreyk 	struct bstp_port	*bs_root_port;
386b1b9d014Sreyk 	u_int8_t		bs_protover;
387b1b9d014Sreyk 	u_int16_t		bs_migration_delay;
388b1b9d014Sreyk 	u_int16_t		bs_edge_delay;
389b1b9d014Sreyk 	u_int16_t		bs_bridge_max_age;
390b1b9d014Sreyk 	u_int16_t		bs_bridge_fdelay;
391b1b9d014Sreyk 	u_int16_t		bs_bridge_htime;
392b1b9d014Sreyk 	u_int16_t		bs_root_msg_age;
393b1b9d014Sreyk 	u_int16_t		bs_root_max_age;
394b1b9d014Sreyk 	u_int16_t		bs_root_fdelay;
395b1b9d014Sreyk 	u_int16_t		bs_root_htime;
396b1b9d014Sreyk 	u_int16_t		bs_hold_time;
397b1b9d014Sreyk 	u_int16_t		bs_bridge_priority;
398b1b9d014Sreyk 	u_int8_t		bs_txholdcount;
399b1b9d014Sreyk 	u_int8_t		bs_allsynced;
400b1b9d014Sreyk 	struct timeout		bs_bstptimeout;		/* stp timeout */
401b1b9d014Sreyk 	struct bstp_timer	bs_link_timer;
402b1b9d014Sreyk 	struct timeval		bs_last_tc_time;
403b1b9d014Sreyk 	LIST_HEAD(, bstp_port)	bs_bplist;
404b1b9d014Sreyk };
405b1b9d014Sreyk 
4069fa0b7aaSjason /*
4079fa0b7aaSjason  * Bridge interface list
408282291edSmpi  *
409282291edSmpi  *  Locks used to protect struct members in this file:
410282291edSmpi  *	I	immutable after creation
411282291edSmpi  *	k	kernel lock
4129fa0b7aaSjason  */
4139fa0b7aaSjason struct bridge_iflist {
414282291edSmpi 	SMR_SLIST_ENTRY(bridge_iflist)	bif_next;	/* [k] next in list */
415282291edSmpi 	struct bridge_softc		*bridge_sc;	/* [I] sc backpointer */
416282291edSmpi 	struct bstp_port		*bif_stp;	/* [I] STP port state */
417282291edSmpi 	struct brl_head			bif_brlin;	/* [k] input rules */
418282291edSmpi 	struct brl_head			bif_brlout;	/* [k] output rules */
419282291edSmpi 	struct ifnet			*ifp;		/* [I] net interface */
4209fa0b7aaSjason 	u_int32_t			bif_flags;	/* member flags */
4210a04437dSmpi 	u_int32_t			bif_protected;	/* protected domains */
4223fe9d1bdSdlg 	struct task			bif_dtask;
4239fa0b7aaSjason };
424b1b9d014Sreyk #define bif_state			bif_stp->bp_state
4259fa0b7aaSjason 
4269fa0b7aaSjason /*
42724d7e143Sclaudio  * XXX ip_ipsp.h's sockaddr_union should be converted to sockaddr *
42824d7e143Sclaudio  * passing with correct sa_len, then a good approach for cleaning this
42924d7e143Sclaudio  * will become more clear.
43024d7e143Sclaudio  */
43124d7e143Sclaudio union brsockaddr_union {
43224d7e143Sclaudio 	struct sockaddr		sa;
43324d7e143Sclaudio 	struct sockaddr_in	sin;
43424d7e143Sclaudio 	struct sockaddr_in6	sin6;
43524d7e143Sclaudio };
43624d7e143Sclaudio 
43724d7e143Sclaudio /*
43826334ce3Sreyk  * Bridge tunnel tagging
43926334ce3Sreyk  */
44026334ce3Sreyk struct bridge_tunneltag {
44124d7e143Sclaudio 	union brsockaddr_union		brtag_peer;
44224d7e143Sclaudio 	union brsockaddr_union		brtag_local;
44326334ce3Sreyk 	u_int32_t			brtag_id;
44426334ce3Sreyk };
44526334ce3Sreyk 
44626334ce3Sreyk /*
4479fa0b7aaSjason  * Bridge route node
4489fa0b7aaSjason  */
4499fa0b7aaSjason struct bridge_rtnode {
4509fa0b7aaSjason 	LIST_ENTRY(bridge_rtnode)	brt_next;	/* next in list */
45196c4247cSmpi 	unsigned int			brt_ifidx;	/* destination ifs */
4529fa0b7aaSjason 	u_int8_t			brt_flags;	/* address flags */
4539fa0b7aaSjason 	u_int8_t			brt_age;	/* age counter */
4549fa0b7aaSjason 	struct ether_addr		brt_addr;	/* dst addr */
45526334ce3Sreyk 	struct bridge_tunneltag		brt_tunnel;	/* tunnel endpoint */
4569fa0b7aaSjason };
45741b46478Smpi #define brt_family brt_tunnel.brtag_peer.sa.sa_family
4589fa0b7aaSjason 
4592fd37929Scamield #ifndef BRIDGE_RTABLE_SIZE
4602fd37929Scamield #define BRIDGE_RTABLE_SIZE	1024
4612fd37929Scamield #endif
4622fd37929Scamield #define BRIDGE_RTABLE_MASK	(BRIDGE_RTABLE_SIZE - 1)
4632fd37929Scamield 
4649fa0b7aaSjason /*
465282291edSmpi  * Software state for each bridge
466282291edSmpi  *
46796d0f2aeSmpi  *  Locks used to protect struct members in this file:
46896d0f2aeSmpi  *	I	immutable after creation
46996d0f2aeSmpi  *	m	per-softc mutex
47096c4247cSmpi  *	k	kernel lock
47196d0f2aeSmpi  */
4729fa0b7aaSjason struct bridge_softc {
4739fa0b7aaSjason 	struct ifnet			sc_if;	/* the interface */
47496d0f2aeSmpi 	uint32_t			sc_brtmax;	/* [m] max # addresses */
47596d0f2aeSmpi 	uint32_t			sc_brtcnt;	/* [m] current # addrs */
47699b6c6e1Shenning 	int				sc_brttimeout;	/* timeout ticks */
47796d0f2aeSmpi 	uint64_t			sc_hashkey[2];	/* [I] siphash key */
4789fa0b7aaSjason 	struct timeout			sc_brtimeout;	/* timeout state */
479b1b9d014Sreyk 	struct bstp_state		*sc_stp;	/* stp state */
480282291edSmpi 	SMR_SLIST_HEAD(, bridge_iflist)	sc_iflist;	/* [k] interface list */
481282291edSmpi 	SMR_SLIST_HEAD(, bridge_iflist)	sc_spanlist;	/* [k] span ports */
48296d0f2aeSmpi 	struct mutex			sc_mtx;		/* mutex */
48396d0f2aeSmpi 	LIST_HEAD(, bridge_rtnode)	sc_rts[BRIDGE_RTABLE_SIZE];	/* [m] hash table */
4849fa0b7aaSjason };
4859fa0b7aaSjason 
486b1b9d014Sreyk extern const u_int8_t bstp_etheraddr[];
487062b28b9Sgoda struct llc;
4889fa0b7aaSjason 
48996c4247cSmpi int	bridge_enqueue(struct ifnet *, struct mbuf *);
490b64f3d33Sreyk void	bridge_update(struct ifnet *, struct ether_addr *, int);
4913482c5fdSmarkus void	bridge_rtdelete(struct bridge_softc *, struct ifnet *, int);
492b1b9d014Sreyk void	bridge_rtagenode(struct ifnet *, int);
49326334ce3Sreyk struct bridge_tunneltag *bridge_tunnel(struct mbuf *);
49426334ce3Sreyk struct bridge_tunneltag *bridge_tunneltag(struct mbuf *);
495d72e8ec4Sreyk void	bridge_tunneluntag(struct mbuf *);
496062b28b9Sgoda void	bridge_copyaddr(struct sockaddr *, struct sockaddr *);
49726334ce3Sreyk void	bridge_copytag(struct bridge_tunneltag *, struct bridge_tunneltag *);
498b1b9d014Sreyk 
49913dba897Smvs struct bstp_state *bstp_create(void);
50013dba897Smvs void	bstp_enable(struct bstp_state *bs, unsigned int);
50113dba897Smvs void	bstp_disable(struct bstp_state *bs);
502b1b9d014Sreyk void	bstp_destroy(struct bstp_state *);
503b1b9d014Sreyk void	bstp_initialization(struct bstp_state *);
504b1b9d014Sreyk void	bstp_stop(struct bstp_state *);
505b1b9d014Sreyk int	bstp_ioctl(struct ifnet *, u_long, caddr_t);
506b1b9d014Sreyk struct bstp_port *bstp_add(struct bstp_state *, struct ifnet *);
507b1b9d014Sreyk void	bstp_delete(struct bstp_port *);
508397a64b3Smpf struct mbuf *bstp_input(struct bstp_state *, struct bstp_port *,
509b1b9d014Sreyk     struct ether_header *, struct mbuf *);
510b1b9d014Sreyk void	bstp_ifstate(void *);
511b1b9d014Sreyk u_int8_t bstp_getstate(struct bstp_state *, struct bstp_port *);
512b1b9d014Sreyk void	bstp_ifsflags(struct bstp_port *, u_int);
513062b28b9Sgoda 
514062b28b9Sgoda int	bridgectl_ioctl(struct ifnet *, u_long, caddr_t);
51529016cb9Smpi int	bridge_rtupdate(struct bridge_softc *,
51696c4247cSmpi     struct ether_addr *, struct ifnet *, int, u_int8_t, struct mbuf *);
51796c4247cSmpi unsigned int bridge_rtlookup(struct ifnet *,
51833d9f1d5Smpi     struct ether_addr *, struct mbuf *);
519062b28b9Sgoda void	bridge_rtflush(struct bridge_softc *, int);
520abb517abSmpi void	bridge_rtage(void *);
521062b28b9Sgoda 
522062b28b9Sgoda u_int8_t bridge_filterrule(struct brl_head *, struct ether_header *,
523062b28b9Sgoda     struct mbuf *);
524062b28b9Sgoda void	bridge_flushrule(struct bridge_iflist *);
52570d427baSgoda 
5261cfe6aaaSmpi void	bridge_fragment(struct ifnet *, struct ifnet *, struct ether_header *,
5271cfe6aaaSmpi     struct mbuf *);
52896c4247cSmpi struct bridge_iflist *bridge_getbif(struct ifnet *);
529044aaac6Smvs int	bridge_findbif(struct bridge_softc *, const char *,
530044aaac6Smvs     struct bridge_iflist **);
531062b28b9Sgoda 
532d4773ae9Sjason #endif /* _KERNEL */
533e04c8cc2Sangelos #endif /* _NET_IF_BRIDGE_H_ */
534