Annotation of sys/net/if_bridge.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_bridge.h,v 1.31 2006/12/11 22:11:48 reyk 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: LIST_ENTRY(bstp_state) bs_list;
358: struct ifnet *bs_ifp;
359: struct bstp_pri_vector bs_bridge_pv;
360: struct bstp_pri_vector bs_root_pv;
361: struct bstp_port *bs_root_port;
362: u_int8_t bs_protover;
363: u_int16_t bs_migration_delay;
364: u_int16_t bs_edge_delay;
365: u_int16_t bs_bridge_max_age;
366: u_int16_t bs_bridge_fdelay;
367: u_int16_t bs_bridge_htime;
368: u_int16_t bs_root_msg_age;
369: u_int16_t bs_root_max_age;
370: u_int16_t bs_root_fdelay;
371: u_int16_t bs_root_htime;
372: u_int16_t bs_hold_time;
373: u_int16_t bs_bridge_priority;
374: u_int8_t bs_txholdcount;
375: u_int8_t bs_allsynced;
376: struct timeout bs_bstptimeout; /* stp timeout */
377: struct bstp_timer bs_link_timer;
378: struct timeval bs_last_tc_time;
379: LIST_HEAD(, bstp_port) bs_bplist;
380: };
381: #define bs_ifflags bs_ifp->if_flags
382:
383: /*
384: * Bridge interface list
385: */
386: struct bridge_iflist {
387: LIST_ENTRY(bridge_iflist) next; /* next in list */
388: struct bstp_port *bif_stp; /* STP port state */
389: struct brl_head bif_brlin; /* input rules */
390: struct brl_head bif_brlout; /* output rules */
391: struct ifnet *ifp; /* member interface */
392: u_int32_t bif_flags; /* member flags */
393: };
394: #define bif_state bif_stp->bp_state
395:
396: /*
397: * Bridge route node
398: */
399: struct bridge_rtnode {
400: LIST_ENTRY(bridge_rtnode) brt_next; /* next in list */
401: struct ifnet *brt_if; /* destination ifs */
402: u_int8_t brt_flags; /* address flags */
403: u_int8_t brt_age; /* age counter */
404: struct ether_addr brt_addr; /* dst addr */
405: };
406:
407: #ifndef BRIDGE_RTABLE_SIZE
408: #define BRIDGE_RTABLE_SIZE 1024
409: #endif
410: #define BRIDGE_RTABLE_MASK (BRIDGE_RTABLE_SIZE - 1)
411:
412: /*
413: * Software state for each bridge
414: */
415: struct bridge_softc {
416: struct ifnet sc_if; /* the interface */
417: LIST_ENTRY(bridge_softc) sc_list; /* all bridges */
418: struct bridge_iflist *sc_root_port;
419: u_int32_t sc_brtmax; /* max # addresses */
420: u_int32_t sc_brtcnt; /* current # addrs */
421: int sc_brttimeout; /* timeout ticks */
422: u_int32_t sc_hashkey; /* hash key */
423: struct timeout sc_brtimeout; /* timeout state */
424: struct bstp_state *sc_stp; /* stp state */
425: LIST_HEAD(, bridge_iflist) sc_iflist; /* interface list */
426: LIST_HEAD(, bridge_rtnode) sc_rts[BRIDGE_RTABLE_SIZE]; /* hash table */
427: LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports */
428: };
429:
430: extern const u_int8_t bstp_etheraddr[];
431:
432: void bridge_ifdetach(struct ifnet *);
433: struct mbuf *bridge_input(struct ifnet *, struct ether_header *,
434: struct mbuf *);
435: int bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
436: struct rtentry *);
437: void bridge_update(struct ifnet *, struct ether_addr *, int);
438: void bridge_rtdelete(struct bridge_softc *, struct ifnet *, int);
439: void bridge_rtagenode(struct ifnet *, int);
440:
441: void bstp_attach(int);
442: struct bstp_state *bstp_create(struct ifnet *);
443: void bstp_destroy(struct bstp_state *);
444: void bstp_initialization(struct bstp_state *);
445: void bstp_stop(struct bstp_state *);
446: int bstp_ioctl(struct ifnet *, u_long, caddr_t);
447: struct bstp_port *bstp_add(struct bstp_state *, struct ifnet *);
448: void bstp_delete(struct bstp_port *);
449: struct mbuf *bstp_input(struct bstp_state *, struct bstp_port *,
450: struct ether_header *, struct mbuf *);
451: void bstp_ifstate(void *);
452: u_int8_t bstp_getstate(struct bstp_state *, struct bstp_port *);
453: void bstp_ifsflags(struct bstp_port *, u_int);
454: #endif /* _KERNEL */
455: #endif /* _NET_IF_BRIDGE_H_ */
CVSweb