1 /*	$OpenBSD: if_bridge.h,v 1.26 2003/12/03 14:55:58 markus Exp $	*/
2 
3 /*
4  * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Effort sponsored in part by the Defense Advanced Research Projects
29  * Agency (DARPA) and Air Force Research Laboratory, Air Force
30  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
31  *
32  */
33 
34 #ifndef _NET_IF_BRIDGE_H_
35 #define _NET_IF_BRIDGE_H_
36 
37 #include <net/pfvar.h>
38 
39 /*
40  * Bridge control request: add/delete member interfaces.
41  */
42 struct ifbreq {
43 	char		ifbr_name[IFNAMSIZ];	/* bridge ifs name */
44 	char		ifbr_ifsname[IFNAMSIZ];	/* member ifs name */
45 	u_int32_t	ifbr_ifsflags;		/* member ifs flags */
46 	u_int8_t	ifbr_state;		/* member stp state */
47 	u_int8_t	ifbr_priority;		/* member stp priority */
48 	u_int8_t	ifbr_portno;		/* member port number */
49 	u_int32_t	ifbr_path_cost;		/* member stp path cost */
50 };
51 /* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */
52 #define	IFBIF_LEARNING		0x0001	/* ifs can learn */
53 #define	IFBIF_DISCOVER		0x0002	/* ifs sends packets w/unknown dest */
54 #define	IFBIF_BLOCKNONIP	0x0004	/* ifs blocks non-IP/ARP in/out */
55 #define	IFBIF_STP		0x0008	/* ifs participates in spanning tree */
56 #define	IFBIF_SPAN		0x0100	/* ifs is a span port (ro) */
57 #define	IFBIF_RO_MASK		0xff00	/* read only bits */
58 /* SIOCBRDGFLUSH */
59 #define	IFBF_FLUSHDYN	0x0	/* flush dynamic addresses only */
60 #define	IFBF_FLUSHALL	0x1	/* flush all addresses from cache */
61 
62 /* port states */
63 #define	BSTP_IFSTATE_DISABLED	0
64 #define	BSTP_IFSTATE_LISTENING	1
65 #define	BSTP_IFSTATE_LEARNING	2
66 #define	BSTP_IFSTATE_FORWARDING	3
67 #define	BSTP_IFSTATE_BLOCKING	4
68 
69 /*
70  * Interface list structure
71  */
72 struct ifbifconf {
73 	char		ifbic_name[IFNAMSIZ];	/* bridge ifs name */
74 	u_int32_t	ifbic_len;		/* buffer size */
75 	union {
76 		caddr_t	ifbicu_buf;
77 		struct	ifbreq *ifbicu_req;
78 	} ifbic_ifbicu;
79 #define	ifbic_buf	ifbic_ifbicu.ifbicu_buf
80 #define	ifbic_req	ifbic_ifbicu.ifbicu_req
81 };
82 
83 /*
84  * Bridge address request
85  */
86 struct ifbareq {
87 	char			ifba_name[IFNAMSIZ];	/* bridge name */
88 	char			ifba_ifsname[IFNAMSIZ];	/* destination ifs */
89 	u_int8_t		ifba_age;		/* address age */
90 	u_int8_t		ifba_flags;		/* address flags */
91 	struct ether_addr	ifba_dst;		/* destination addr */
92 };
93 
94 #define	IFBAF_TYPEMASK		0x03		/* address type mask */
95 #define	IFBAF_DYNAMIC		0x00		/* dynamically learned */
96 #define	IFBAF_STATIC		0x01		/* static address */
97 
98 struct ifbaconf {
99 	char			ifbac_name[IFNAMSIZ];	/* bridge ifs name */
100 	u_int32_t		ifbac_len;		/* buffer size */
101 	union {
102 		caddr_t	ifbacu_buf;			/* buffer */
103 		struct ifbareq *ifbacu_req;		/* request pointer */
104 	} ifbac_ifbacu;
105 #define	ifbac_buf	ifbac_ifbacu.ifbacu_buf
106 #define	ifbac_req	ifbac_ifbacu.ifbacu_req
107 };
108 
109 struct ifbrparam {
110 	char			ifbrp_name[IFNAMSIZ];
111 	union {
112 		u_int32_t	ifbrpu_csize;		/* cache size */
113 		int		ifbrpu_ctime;		/* cache time (sec) */
114 		u_int16_t	ifbrpu_prio;		/* bridge priority */
115 		u_int8_t	ifbrpu_hellotime;	/* hello time (sec) */
116 		u_int8_t	ifbrpu_fwddelay;	/* fwd delay (sec) */
117 		u_int8_t	ifbrpu_maxage;		/* max age (sec) */
118 	} ifbrp_ifbrpu;
119 };
120 #define	ifbrp_csize	ifbrp_ifbrpu.ifbrpu_csize
121 #define	ifbrp_ctime	ifbrp_ifbrpu.ifbrpu_ctime
122 #define	ifbrp_prio	ifbrp_ifbrpu.ifbrpu_prio
123 #define	ifbrp_hellotime	ifbrp_ifbrpu.ifbrpu_hellotime
124 #define	ifbrp_fwddelay	ifbrp_ifbrpu.ifbrpu_fwddelay
125 #define	ifbrp_maxage	ifbrp_ifbrpu.ifbrpu_maxage
126 
127 /*
128  * Bridge mac rules
129  */
130 struct ifbrlreq {
131 	char			ifbr_name[IFNAMSIZ];	/* bridge ifs name */
132 	char			ifbr_ifsname[IFNAMSIZ];	/* member ifs name */
133 	u_int8_t		ifbr_action;		/* disposition */
134 	u_int8_t		ifbr_flags;		/* flags */
135 	struct ether_addr	ifbr_src;		/* source mac */
136 	struct ether_addr	ifbr_dst;		/* destination mac */
137 	char			ifbr_tagname[PF_TAG_NAME_SIZE];	/* pf tagname */
138 };
139 #define	BRL_ACTION_BLOCK	0x01			/* block frame */
140 #define	BRL_ACTION_PASS		0x02			/* pass frame */
141 #define	BRL_FLAG_IN		0x08			/* input rule */
142 #define	BRL_FLAG_OUT		0x04			/* output rule */
143 #define	BRL_FLAG_SRCVALID	0x02			/* src valid */
144 #define	BRL_FLAG_DSTVALID	0x01			/* dst valid */
145 
146 struct ifbrlconf {
147 	char		ifbrl_name[IFNAMSIZ];	/* bridge ifs name */
148 	char		ifbrl_ifsname[IFNAMSIZ];/* member ifs name */
149 	u_int32_t	ifbrl_len;		/* buffer size */
150 	union {
151 		caddr_t	ifbrlu_buf;
152 		struct	ifbrlreq *ifbrlu_req;
153 	} ifbrl_ifbrlu;
154 #define	ifbrl_buf	ifbrl_ifbrlu.ifbrlu_buf
155 #define	ifbrl_req	ifbrl_ifbrlu.ifbrlu_req
156 };
157 
158 #ifdef _KERNEL
159 /*
160  * Bridge filtering rules
161  */
162 SIMPLEQ_HEAD(brl_head, brl_node);
163 
164 struct brl_node {
165 	SIMPLEQ_ENTRY(brl_node)	brl_next;	/* next rule */
166 	struct ether_addr	brl_src;	/* source mac address */
167 	struct ether_addr	brl_dst;	/* destination mac address */
168 	u_int16_t		brl_tag;	/* pf tag ID */
169 	u_int8_t		brl_action;	/* what to do with match */
170 	u_int8_t		brl_flags;	/* comparison flags */
171 };
172 
173 struct bridge_timer {
174 	u_int16_t active;
175 	u_int16_t value;
176 };
177 
178 struct bstp_config_unit {
179 	u_int64_t	cu_rootid;
180 	u_int64_t	cu_bridge_id;
181 	u_int32_t	cu_root_path_cost;
182 	u_int16_t	cu_message_age;
183 	u_int16_t	cu_max_age;
184 	u_int16_t	cu_hello_time;
185 	u_int16_t	cu_forward_delay;
186 	u_int16_t	cu_port_id;
187 	u_int8_t	cu_message_type;
188 	u_int8_t	cu_topology_change_acknowledgment;
189 	u_int8_t	cu_topology_change;
190 };
191 
192 struct bstp_tcn_unit {
193 	u_int8_t	tu_message_type;
194 };
195 
196 /*
197  * Bridge interface list
198  */
199 struct bridge_iflist {
200 	LIST_ENTRY(bridge_iflist)	next;		/* next in list */
201 	u_int64_t			bif_designated_root;
202 	u_int64_t			bif_designated_bridge;
203 	u_int32_t			bif_path_cost;
204 	u_int32_t			bif_designated_cost;
205 	struct bridge_timer		bif_hold_timer;
206 	struct bridge_timer		bif_message_age_timer;
207 	struct bridge_timer		bif_forward_delay_timer;
208 	struct bstp_config_unit		bif_config_bpdu;
209 	u_int16_t			bif_port_id;
210 	u_int16_t			bif_designated_port;
211 	u_int8_t			bif_state;
212 	u_int8_t			bif_topology_change_acknowledge;
213 	u_int8_t			bif_config_pending;
214 	u_int8_t			bif_change_detection_enabled;
215 	u_int8_t			bif_priority;
216 	struct brl_head			bif_brlin;	/* input rules */
217 	struct brl_head			bif_brlout;	/* output rules */
218 	struct				ifnet *ifp;	/* member interface */
219 	u_int32_t			bif_flags;	/* member flags */
220 };
221 
222 /*
223  * Bridge route node
224  */
225 struct bridge_rtnode {
226 	LIST_ENTRY(bridge_rtnode)	brt_next;	/* next in list */
227 	struct				ifnet *brt_if;	/* destination ifs */
228 	u_int8_t			brt_flags;	/* address flags */
229 	u_int8_t			brt_age;	/* age counter */
230 	struct				ether_addr brt_addr;	/* dst addr */
231 };
232 
233 /*
234  * Software state for each bridge
235  */
236 struct bridge_softc {
237 	struct				ifnet sc_if;	/* the interface */
238 	LIST_ENTRY(bridge_softc)	sc_list;	/* all bridges */
239 	u_int64_t			sc_designated_root;
240 	u_int64_t			sc_bridge_id;
241 	struct bridge_iflist		*sc_root_port;
242 	u_int32_t			sc_root_path_cost;
243 	u_int16_t			sc_max_age;
244 	u_int16_t			sc_hello_time;
245 	u_int16_t			sc_forward_delay;
246 	u_int16_t			sc_bridge_max_age;
247 	u_int16_t			sc_bridge_hello_time;
248 	u_int16_t			sc_bridge_forward_delay;
249 	u_int16_t			sc_topology_change_time;
250 	u_int16_t			sc_hold_time;
251 	u_int16_t			sc_bridge_priority;
252 	u_int8_t			sc_topology_change_detected;
253 	u_int8_t			sc_topology_change;
254 	struct bridge_timer		sc_hello_timer;
255 	struct bridge_timer		sc_topology_change_timer;
256 	struct bridge_timer		sc_tcn_timer;
257 	u_int32_t			sc_brtmax;	/* max # addresses */
258 	u_int32_t			sc_brtcnt;	/* current # addrs */
259 	int				sc_brttimeout;	/* timeout ticks */
260 	u_int32_t			sc_hashkey;	/* hash key */
261 	struct timeout			sc_brtimeout;	/* timeout state */
262 	struct timeout			sc_bstptimeout;	/* stp timeout */
263 	LIST_HEAD(, bridge_iflist)	sc_iflist;	/* interface list */
264 	LIST_HEAD(bridge_rthead, bridge_rtnode)	*sc_rts;/* hash table */
265 	LIST_HEAD(, bridge_iflist)	sc_spanlist;	/* span ports */
266 };
267 
268 extern u_int8_t bstp_etheraddr[];
269 
270 void	bridge_ifdetach(struct ifnet *);
271 struct mbuf *bridge_input(struct ifnet *, struct ether_header *,
272     struct mbuf *);
273 int	bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
274     struct rtentry *);
275 struct mbuf *bstp_input(struct bridge_softc *, struct ifnet *,
276     struct ether_header *, struct mbuf *);
277 void	bstp_initialization(struct bridge_softc *);
278 int	bstp_ioctl(struct ifnet *, u_long, caddr_t);
279 void	bridge_rtdelete(struct bridge_softc *, struct ifnet *, int);
280 #endif /* _KERNEL */
281 #endif /* _NET_IF_BRIDGE_H_ */
282