master
  1/*	$NetBSD: if_bridgevar.h,v 1.37.4.1 2024/09/05 09:27:12 martin Exp $	*/
  2
  3/*
  4 * Copyright 2001 Wasabi Systems, Inc.
  5 * All rights reserved.
  6 *
  7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
  8 *
  9 * Redistribution and use in source and binary forms, with or without
 10 * modification, are permitted provided that the following conditions
 11 * are met:
 12 * 1. Redistributions of source code must retain the above copyright
 13 *    notice, this list of conditions and the following disclaimer.
 14 * 2. Redistributions in binary form must reproduce the above copyright
 15 *    notice, this list of conditions and the following disclaimer in the
 16 *    documentation and/or other materials provided with the distribution.
 17 * 3. All advertising materials mentioning features or use of this software
 18 *    must display the following acknowledgement:
 19 *	This product includes software developed for the NetBSD Project by
 20 *	Wasabi Systems, Inc.
 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
 22 *    or promote products derived from this software without specific prior
 23 *    written permission.
 24 *
 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 28 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 35 * POSSIBILITY OF SUCH DAMAGE.
 36 */
 37
 38/*
 39 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
 40 * All rights reserved.
 41 *
 42 * Redistribution and use in source and binary forms, with or without
 43 * modification, are permitted provided that the following conditions
 44 * are met:
 45 * 1. Redistributions of source code must retain the above copyright
 46 *    notice, this list of conditions and the following disclaimer.
 47 * 2. Redistributions in binary form must reproduce the above copyright
 48 *    notice, this list of conditions and the following disclaimer in the
 49 *    documentation and/or other materials provided with the distribution.
 50 * 3. All advertising materials mentioning features or use of this software
 51 *    must display the following acknowledgement:
 52 *	This product includes software developed by Jason L. Wright
 53 * 4. The name of the author may not be used to endorse or promote products
 54 *    derived from this software without specific prior written permission.
 55 *
 56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 59 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 60 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 61 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 62 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 65 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 66 * POSSIBILITY OF SUCH DAMAGE.
 67 *
 68 * OpenBSD: if_bridge.h,v 1.14 2001/03/22 03:48:29 jason Exp
 69 */
 70
 71/*
 72 * Data structure and control definitions for bridge interfaces.
 73 */
 74
 75#ifndef _NET_IF_BRIDGEVAR_H_
 76#define _NET_IF_BRIDGEVAR_H_
 77
 78#include <sys/callout.h>
 79#include <sys/queue.h>
 80#include <sys/mutex.h>
 81#include <sys/condvar.h>
 82
 83/*
 84 * Commands used in the SIOCSDRVSPEC ioctl.  Note the lookup of the
 85 * bridge interface itself is keyed off the ifdrv structure.
 86 */
 87#define	BRDGADD			0	/* add bridge member (ifbreq) */
 88#define	BRDGDEL			1	/* delete bridge member (ifbreq) */
 89#define	BRDGGIFFLGS		2	/* get member if flags (ifbreq) */
 90#define	BRDGSIFFLGS		3	/* set member if flags (ifbreq) */
 91#define	BRDGSCACHE		4	/* set cache size (ifbrparam) */
 92#define	BRDGGCACHE		5	/* get cache size (ifbrparam) */
 93#define	OBRDGGIFS		6	/* get member list (ifbifconf) */
 94#define	OBRDGRTS		7	/* get address list (ifbaconf) */
 95#define	BRDGSADDR		8	/* set static address (ifbareq) */
 96#define	BRDGSTO			9	/* set cache timeout (ifbrparam) */
 97#define	BRDGGTO			10	/* get cache timeout (ifbrparam) */
 98#define	BRDGDADDR		11	/* delete address (ifbareq) */
 99#define	BRDGFLUSH		12	/* flush address cache (ifbreq) */
100
101#define	BRDGGPRI		13	/* get priority (ifbrparam) */
102#define	BRDGSPRI		14	/* set priority (ifbrparam) */
103#define	BRDGGHT			15	/* get hello time (ifbrparam) */
104#define	BRDGSHT			16	/* set hello time (ifbrparam) */
105#define	BRDGGFD			17	/* get forward delay (ifbrparam) */
106#define	BRDGSFD			18	/* set forward delay (ifbrparam) */
107#define	BRDGGMA			19	/* get max age (ifbrparam) */
108#define	BRDGSMA			20	/* set max age (ifbrparam) */
109#define	BRDGSIFPRIO		21	/* set if priority (ifbreq) */
110#define BRDGSIFCOST		22	/* set if path cost (ifbreq) */
111#define BRDGGFILT	        23	/* get filter flags (ifbrparam) */
112#define BRDGSFILT	        24	/* set filter flags (ifbrparam) */
113
114#define	BRDGGIFS		25	/* get member list */
115#define	BRDGRTS			26	/* get address list */
116
117/*
118 * Generic bridge control request.
119 */
120struct ifbreq {
121	char		ifbr_ifsname[IFNAMSIZ];	/* member if name */
122	uint32_t	ifbr_ifsflags;		/* member if flags */
123	uint8_t		ifbr_state;		/* member if STP state */
124	uint8_t		ifbr_priority;		/* member if STP priority */
125	uint8_t		ifbr_path_cost;		/* member if STP cost */
126	uint8_t		ifbr_portno;		/* member if port number */
127};
128
129/* BRDGGIFFLAGS, BRDGSIFFLAGS */
130#define	IFBIF_LEARNING		0x01	/* if can learn */
131#define	IFBIF_DISCOVER		0x02	/* if sends packets w/ unknown dest. */
132#define	IFBIF_STP		0x04	/* if participates in spanning tree */
133#define	IFBIF_PROTECTED		0x08	/* if participates in protected mode */
134
135#define	IFBIFBITS	"\020\1LEARNING\2DISCOVER\3STP\4PROTECTED"
136
137/* BRDGFLUSH */
138#define	IFBF_FLUSHDYN		0x00	/* flush learned addresses only */
139#define	IFBF_FLUSHALL		0x01	/* flush all addresses */
140
141/* BRDGSFILT */
142#define IFBF_FILT_USEIPF	0x00000001 /* enable ipf on bridge */
143#define IFBF_FILT_MASK		0x00000001 /* mask of valid values */
144
145/* STP port states */
146#define	BSTP_IFSTATE_DISABLED	0
147#define	BSTP_IFSTATE_LISTENING	1
148#define	BSTP_IFSTATE_LEARNING	2
149#define	BSTP_IFSTATE_FORWARDING	3
150#define	BSTP_IFSTATE_BLOCKING	4
151
152/*
153 * Interface list structure.
154 */
155struct ifbifconf {
156	uint32_t	ifbic_len;	/* buffer size */
157	union {
158		void *	ifbicu_buf;
159		struct ifbreq *ifbicu_req;
160	} ifbic_ifbicu;
161#define	ifbic_buf	ifbic_ifbicu.ifbicu_buf
162#define	ifbic_req	ifbic_ifbicu.ifbicu_req
163};
164
165/*
166 * Bridge address request.
167 */
168struct ifbareq {
169	char		ifba_ifsname[IFNAMSIZ];	/* member if name */
170	time_t		ifba_expire;		/* address expire time */
171	uint8_t		ifba_flags;		/* address flags */
172	uint8_t		ifba_dst[ETHER_ADDR_LEN];/* destination address */
173};
174
175#define	IFBAF_TYPEMASK	0x03	/* address type mask */
176#define	IFBAF_DYNAMIC	0x00	/* dynamically learned address */
177#define	IFBAF_STATIC	0x01	/* static address */
178
179#define	IFBAFBITS	"\020\1STATIC"
180
181/*
182 * Address list structure.
183 */
184struct ifbaconf {
185	uint32_t	ifbac_len;	/* buffer size */
186	union {
187		void *ifbacu_buf;
188		struct ifbareq *ifbacu_req;
189	} ifbac_ifbacu;
190#define	ifbac_buf	ifbac_ifbacu.ifbacu_buf
191#define	ifbac_req	ifbac_ifbacu.ifbacu_req
192};
193
194/*
195 * Bridge parameter structure.
196 */
197struct ifbrparam {
198	union {
199		uint32_t ifbrpu_int32;
200		uint16_t ifbrpu_int16;
201		uint8_t ifbrpu_int8;
202	} ifbrp_ifbrpu;
203};
204#define	ifbrp_csize	ifbrp_ifbrpu.ifbrpu_int32	/* cache size */
205#define	ifbrp_ctime	ifbrp_ifbrpu.ifbrpu_int32	/* cache time (sec) */
206#define	ifbrp_prio	ifbrp_ifbrpu.ifbrpu_int16	/* bridge priority */
207#define	ifbrp_hellotime	ifbrp_ifbrpu.ifbrpu_int8	/* hello time (sec) */
208#define	ifbrp_fwddelay	ifbrp_ifbrpu.ifbrpu_int8	/* fwd time (sec) */
209#define	ifbrp_maxage	ifbrp_ifbrpu.ifbrpu_int8	/* max age (sec) */
210#define	ifbrp_filter	ifbrp_ifbrpu.ifbrpu_int32	/* filtering flags */
211
212#ifdef _KERNEL
213#ifdef _KERNEL_OPT
214#include "opt_net_mpsafe.h"
215#endif /* _KERNEL_OPT */
216
217#include <sys/pserialize.h>
218#include <sys/pslist.h>
219#include <sys/psref.h>
220#include <sys/workqueue.h>
221
222#include <net/pktqueue.h>
223
224/*
225 * Timekeeping structure used in spanning tree code.
226 */
227struct bridge_timer {
228	uint16_t	active;
229	uint16_t	value;
230};
231
232struct bstp_config_unit {
233	uint64_t	cu_rootid;
234	uint64_t	cu_bridge_id;
235	uint32_t	cu_root_path_cost;
236	uint16_t	cu_message_age;
237	uint16_t	cu_max_age;
238	uint16_t	cu_hello_time;
239	uint16_t	cu_forward_delay;
240	uint16_t	cu_port_id;
241	uint8_t		cu_message_type;
242	uint8_t		cu_topology_change_acknowledgment;
243	uint8_t		cu_topology_change;
244};
245
246struct bstp_tcn_unit {
247	uint8_t		tu_message_type;
248};
249
250/*
251 * Bridge interface list entry.
252 */
253struct bridge_iflist {
254	struct pslist_entry	bif_next;
255	uint64_t		bif_designated_root;
256	uint64_t		bif_designated_bridge;
257	uint32_t		bif_path_cost;
258	uint32_t		bif_designated_cost;
259	struct bridge_timer	bif_hold_timer;
260	struct bridge_timer	bif_message_age_timer;
261	struct bridge_timer	bif_forward_delay_timer;
262	uint16_t		bif_port_id;
263	uint16_t		bif_designated_port;
264	struct bstp_config_unit	bif_config_bpdu;
265	uint8_t			bif_state;
266	uint8_t			bif_topology_change_acknowledge;
267	uint8_t			bif_config_pending;
268	uint8_t			bif_change_detection_enabled;
269	uint8_t			bif_priority;
270	struct ifnet		*bif_ifp;	/* member if */
271	uint32_t		bif_flags;	/* member if flags */
272	struct psref_target	bif_psref;
273	void *			*bif_linkstate_hook;
274	void *			*bif_ifdetach_hook;
275};
276
277/*
278 * Bridge route node.
279 */
280struct bridge_rtnode {
281	struct pslist_entry     brt_hash;	/* hash table linkage */
282	struct pslist_entry     brt_list;	/* list linkage */
283	struct ifnet		*brt_ifp;	/* destination if */
284	time_t			brt_expire;	/* expiration time */
285	uint8_t			brt_flags;	/* address flags */
286	uint8_t			brt_addr[ETHER_ADDR_LEN];
287};
288
289struct bridge_iflist_psref {
290	struct pslist_head	bip_iflist;	/* member interface list */
291	kmutex_t		bip_lock;
292	pserialize_t		bip_psz;
293};
294
295/*
296 * Software state for each bridge.
297 */
298struct bridge_softc {
299	struct ifnet		sc_if;
300	LIST_ENTRY(bridge_softc) sc_list;
301	uint64_t		sc_designated_root;
302	uint64_t		sc_bridge_id;
303	struct bridge_iflist	*sc_root_port;
304	uint32_t		sc_root_path_cost;
305	uint16_t		sc_max_age;
306	uint16_t		sc_hello_time;
307	uint16_t		sc_forward_delay;
308	uint16_t		sc_bridge_max_age;
309	uint16_t		sc_bridge_hello_time;
310	uint16_t		sc_bridge_forward_delay;
311	uint16_t		sc_topology_change_time;
312	uint16_t		sc_hold_time;
313	uint16_t		sc_bridge_priority;
314	uint8_t			sc_topology_change_detected;
315	uint8_t			sc_topology_change;
316	struct bridge_timer	sc_hello_timer;
317	struct bridge_timer	sc_topology_change_timer;
318	struct bridge_timer	sc_tcn_timer;
319	uint32_t		sc_brtmax;	/* max # of addresses */
320	uint32_t		sc_brtcnt;	/* cur. # of addresses */
321	uint32_t		sc_brttimeout;	/* rt timeout in seconds */
322	callout_t		sc_brcallout;	/* bridge callout */
323	callout_t		sc_bstpcallout;	/* STP callout */
324	struct bridge_iflist_psref	sc_iflist_psref;
325	struct pslist_head	*sc_rthash;	/* our forwarding table */
326	struct pslist_head	sc_rtlist;	/* list version of above */
327	kmutex_t		*sc_rtlist_lock;
328	pserialize_t		sc_rtlist_psz;
329	struct workqueue	*sc_rtage_wq;
330	struct work		sc_rtage_wk;
331	uint32_t		sc_rthash_key;	/* key for hash */
332	uint32_t		sc_filter_flags; /* ipf and flags */
333	int			sc_csum_flags_tx;
334	int			sc_capenable;
335};
336
337extern const uint8_t bstp_etheraddr[];
338
339int	bridge_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
340	    const struct rtentry *);
341
342void	bstp_initialization(struct bridge_softc *);
343void	bstp_stop(struct bridge_softc *);
344void	bstp_input(struct bridge_softc *, struct bridge_iflist *, struct mbuf *);
345
346void	bridge_enqueue(struct bridge_softc *, struct ifnet *, struct mbuf *,
347	    int);
348
349void	bridge_calc_csum_flags(struct bridge_softc *);
350
351#define BRIDGE_LOCK_OBJ(_sc)	(&(_sc)->sc_iflist_psref.bip_lock)
352#define BRIDGE_LOCK(_sc)	mutex_enter(BRIDGE_LOCK_OBJ(_sc))
353#define BRIDGE_UNLOCK(_sc)	mutex_exit(BRIDGE_LOCK_OBJ(_sc))
354#define BRIDGE_LOCKED(_sc)	mutex_owned(BRIDGE_LOCK_OBJ(_sc))
355
356#define BRIDGE_PSZ_RENTER(__s)	do { __s = pserialize_read_enter(); } while (0)
357#define BRIDGE_PSZ_REXIT(__s)	do { pserialize_read_exit(__s); } while (0)
358#define BRIDGE_PSZ_PERFORM(_sc)	pserialize_perform((_sc)->sc_iflist_psref.bip_psz)
359
360#define BRIDGE_IFLIST_READER_FOREACH(_bif, _sc) \
361	PSLIST_READER_FOREACH((_bif), &((_sc)->sc_iflist_psref.bip_iflist), \
362	    struct bridge_iflist, bif_next)
363#define BRIDGE_IFLIST_WRITER_FOREACH(_bif, _sc) \
364	PSLIST_WRITER_FOREACH((_bif), &((_sc)->sc_iflist_psref.bip_iflist), \
365	    struct bridge_iflist, bif_next)
366
367/*
368 * Locking notes:
369 * - Updates of sc_iflist are serialized by sc_iflist_lock (an adaptive mutex)
370 *   - The mutex is also used for STP
371 * - Items of sc_iflist (bridge_iflist) is protected by both pserialize
372 *   (sc_iflist_psz) and reference counting (bridge_iflist#bif_refs)
373 * - Before destroying an item of sc_iflist, we have to do pserialize_perform
374 *   and synchronize with the reference counting via a conditional variable
375 *   (sc_iflist_cz)
376 * - Updates of sc_rtlist are serialized by sc_rtlist_lock (an adaptive mutex)
377 *   - The mutex is also used for pserialize
378 * - A workqueue is used to run bridge_rtage in LWP context via bridge_timer callout
379 *   - bridge_rtage uses pserialize that requires non-interrupt context
380 */
381#endif /* _KERNEL */
382#endif /* !_NET_IF_BRIDGEVAR_H_ */