Annotation of sys/net/if_bridge.h, Revision 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