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