1 /* $OpenBSD: if_bridge.h,v 1.39 2013/10/13 12:09:54 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 struct sockaddr_storage ifba_dstsa; /* tunnel endpoint */ 126 }; 127 128 #define IFBAF_TYPEMASK 0x03 /* address type mask */ 129 #define IFBAF_DYNAMIC 0x00 /* dynamically learned */ 130 #define IFBAF_STATIC 0x01 /* static address */ 131 132 struct ifbaconf { 133 char ifbac_name[IFNAMSIZ]; /* bridge ifs name */ 134 u_int32_t ifbac_len; /* buffer size */ 135 union { 136 caddr_t ifbacu_buf; /* buffer */ 137 struct ifbareq *ifbacu_req; /* request pointer */ 138 } ifbac_ifbacu; 139 #define ifbac_buf ifbac_ifbacu.ifbacu_buf 140 #define ifbac_req ifbac_ifbacu.ifbacu_req 141 }; 142 143 struct ifbrparam { 144 char ifbrp_name[IFNAMSIZ]; 145 union { 146 u_int32_t ifbrpu_csize; /* cache size */ 147 int ifbrpu_ctime; /* cache time (sec) */ 148 u_int16_t ifbrpu_prio; /* bridge priority */ 149 u_int8_t ifbrpu_hellotime; /* hello time (sec) */ 150 u_int8_t ifbrpu_fwddelay; /* fwd delay (sec) */ 151 u_int8_t ifbrpu_maxage; /* max age (sec) */ 152 u_int8_t ifbrpu_proto; /* bridge protocol */ 153 u_int8_t ifbrpu_txhc; /* bpdu tx holdcount */ 154 } ifbrp_ifbrpu; 155 }; 156 #define ifbrp_csize ifbrp_ifbrpu.ifbrpu_csize 157 #define ifbrp_ctime ifbrp_ifbrpu.ifbrpu_ctime 158 #define ifbrp_prio ifbrp_ifbrpu.ifbrpu_prio 159 #define ifbrp_proto ifbrp_ifbrpu.ifbrpu_proto 160 #define ifbrp_txhc ifbrp_ifbrpu.ifbrpu_txhc 161 #define ifbrp_hellotime ifbrp_ifbrpu.ifbrpu_hellotime 162 #define ifbrp_fwddelay ifbrp_ifbrpu.ifbrpu_fwddelay 163 #define ifbrp_maxage ifbrp_ifbrpu.ifbrpu_maxage 164 165 /* Protocol versions */ 166 #define BSTP_PROTO_ID 0x00 167 #define BSTP_PROTO_STP 0x00 168 #define BSTP_PROTO_RSTP 0x02 169 #define BSTP_PROTO_MAX BSTP_PROTO_RSTP 170 171 /* 172 * Bridge current operational parameters structure. 173 */ 174 struct ifbropreq { 175 char ifbop_name[IFNAMSIZ]; 176 u_int8_t ifbop_holdcount; 177 u_int8_t ifbop_maxage; 178 u_int8_t ifbop_hellotime; 179 u_int8_t ifbop_fwddelay; 180 u_int8_t ifbop_protocol; 181 u_int16_t ifbop_priority; 182 u_int64_t ifbop_root_bridge; 183 u_int16_t ifbop_root_port; 184 u_int32_t ifbop_root_path_cost; 185 u_int64_t ifbop_desg_bridge; 186 struct timeval ifbop_last_tc_time; 187 }; 188 189 /* 190 * Bridge mac rules 191 */ 192 struct ifbrlreq { 193 char ifbr_name[IFNAMSIZ]; /* bridge ifs name */ 194 char ifbr_ifsname[IFNAMSIZ]; /* member ifs name */ 195 u_int8_t ifbr_action; /* disposition */ 196 u_int8_t ifbr_flags; /* flags */ 197 struct ether_addr ifbr_src; /* source mac */ 198 struct ether_addr ifbr_dst; /* destination mac */ 199 char ifbr_tagname[PF_TAG_NAME_SIZE]; /* pf tagname */ 200 }; 201 #define BRL_ACTION_BLOCK 0x01 /* block frame */ 202 #define BRL_ACTION_PASS 0x02 /* pass frame */ 203 #define BRL_FLAG_IN 0x08 /* input rule */ 204 #define BRL_FLAG_OUT 0x04 /* output rule */ 205 #define BRL_FLAG_SRCVALID 0x02 /* src valid */ 206 #define BRL_FLAG_DSTVALID 0x01 /* dst valid */ 207 208 struct ifbrlconf { 209 char ifbrl_name[IFNAMSIZ]; /* bridge ifs name */ 210 char ifbrl_ifsname[IFNAMSIZ];/* member ifs name */ 211 u_int32_t ifbrl_len; /* buffer size */ 212 union { 213 caddr_t ifbrlu_buf; 214 struct ifbrlreq *ifbrlu_req; 215 } ifbrl_ifbrlu; 216 #define ifbrl_buf ifbrl_ifbrlu.ifbrlu_buf 217 #define ifbrl_req ifbrl_ifbrlu.ifbrlu_req 218 }; 219 220 #ifdef _KERNEL 221 /* STP port flags */ 222 #define BSTP_PORT_CANMIGRATE 0x0001 223 #define BSTP_PORT_NEWINFO 0x0002 224 #define BSTP_PORT_DISPUTED 0x0004 225 #define BSTP_PORT_ADMCOST 0x0008 226 #define BSTP_PORT_AUTOEDGE 0x0010 227 #define BSTP_PORT_AUTOPTP 0x0020 228 229 /* BPDU priority */ 230 #define BSTP_PDU_SUPERIOR 1 231 #define BSTP_PDU_REPEATED 2 232 #define BSTP_PDU_INFERIOR 3 233 #define BSTP_PDU_INFERIORALT 4 234 #define BSTP_PDU_OTHER 5 235 236 /* BPDU flags */ 237 #define BSTP_PDU_PRMASK 0x0c /* Port Role */ 238 #define BSTP_PDU_PRSHIFT 2 /* Port Role offset */ 239 #define BSTP_PDU_F_UNKN 0x00 /* Unknown port (00) */ 240 #define BSTP_PDU_F_ALT 0x01 /* Alt/Backup port (01) */ 241 #define BSTP_PDU_F_ROOT 0x02 /* Root port (10) */ 242 #define BSTP_PDU_F_DESG 0x03 /* Designated port (11) */ 243 244 #define BSTP_PDU_STPMASK 0x81 /* strip unused STP flags */ 245 #define BSTP_PDU_RSTPMASK 0x7f /* strip unused RSTP flags */ 246 #define BSTP_PDU_F_TC 0x01 /* Topology change */ 247 #define BSTP_PDU_F_P 0x02 /* Proposal flag */ 248 #define BSTP_PDU_F_L 0x10 /* Learning flag */ 249 #define BSTP_PDU_F_F 0x20 /* Forwarding flag */ 250 #define BSTP_PDU_F_A 0x40 /* Agreement flag */ 251 #define BSTP_PDU_F_TCA 0x80 /* Topology change ack */ 252 253 /* 254 * Bridge filtering rules 255 */ 256 SIMPLEQ_HEAD(brl_head, brl_node); 257 258 struct brl_node { 259 SIMPLEQ_ENTRY(brl_node) brl_next; /* next rule */ 260 struct ether_addr brl_src; /* source mac address */ 261 struct ether_addr brl_dst; /* destination mac address */ 262 u_int16_t brl_tag; /* pf tag ID */ 263 u_int8_t brl_action; /* what to do with match */ 264 u_int8_t brl_flags; /* comparision flags */ 265 }; 266 267 struct bstp_timer { 268 u_int16_t active; 269 u_int16_t value; 270 u_int32_t latched; 271 }; 272 273 struct bstp_pri_vector { 274 u_int64_t pv_root_id; 275 u_int32_t pv_cost; 276 u_int64_t pv_dbridge_id; 277 u_int16_t pv_dport_id; 278 u_int16_t pv_port_id; 279 }; 280 281 struct bstp_config_unit { 282 struct bstp_pri_vector cu_pv; 283 u_int16_t cu_message_age; 284 u_int16_t cu_max_age; 285 u_int16_t cu_forward_delay; 286 u_int16_t cu_hello_time; 287 u_int8_t cu_message_type; 288 u_int8_t cu_topology_change_ack; 289 u_int8_t cu_topology_change; 290 u_int8_t cu_proposal; 291 u_int8_t cu_agree; 292 u_int8_t cu_learning; 293 u_int8_t cu_forwarding; 294 u_int8_t cu_role; 295 }; 296 297 struct bstp_tcn_unit { 298 u_int8_t tu_message_type; 299 }; 300 301 struct bstp_port { 302 LIST_ENTRY(bstp_port) bp_next; 303 struct ifnet *bp_ifp; /* parent if */ 304 struct bstp_state *bp_bs; 305 void *bp_lhcookie; /* if linkstate hook */ 306 u_int8_t bp_active; 307 u_int8_t bp_protover; 308 u_int32_t bp_flags; 309 u_int32_t bp_path_cost; 310 u_int16_t bp_port_msg_age; 311 u_int16_t bp_port_max_age; 312 u_int16_t bp_port_fdelay; 313 u_int16_t bp_port_htime; 314 u_int16_t bp_desg_msg_age; 315 u_int16_t bp_desg_max_age; 316 u_int16_t bp_desg_fdelay; 317 u_int16_t bp_desg_htime; 318 struct bstp_timer bp_edge_delay_timer; 319 struct bstp_timer bp_forward_delay_timer; 320 struct bstp_timer bp_hello_timer; 321 struct bstp_timer bp_message_age_timer; 322 struct bstp_timer bp_migrate_delay_timer; 323 struct bstp_timer bp_recent_backup_timer; 324 struct bstp_timer bp_recent_root_timer; 325 struct bstp_timer bp_tc_timer; 326 struct bstp_config_unit bp_msg_cu; 327 struct bstp_pri_vector bp_desg_pv; 328 struct bstp_pri_vector bp_port_pv; 329 u_int16_t bp_port_id; 330 u_int8_t bp_state; 331 u_int8_t bp_tcstate; 332 u_int8_t bp_role; 333 u_int8_t bp_infois; 334 u_int8_t bp_tc_ack; 335 u_int8_t bp_tc_prop; 336 u_int8_t bp_fdbflush; 337 u_int8_t bp_priority; 338 u_int8_t bp_ptp_link; 339 u_int8_t bp_agree; 340 u_int8_t bp_agreed; 341 u_int8_t bp_sync; 342 u_int8_t bp_synced; 343 u_int8_t bp_proposing; 344 u_int8_t bp_proposed; 345 u_int8_t bp_operedge; 346 u_int8_t bp_reroot; 347 u_int8_t bp_rcvdtc; 348 u_int8_t bp_rcvdtca; 349 u_int8_t bp_rcvdtcn; 350 u_int32_t bp_forward_transitions; 351 u_int8_t bp_txcount; 352 }; 353 354 /* 355 * Software state for each bridge STP. 356 */ 357 struct bstp_state { 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 TAILQ_ENTRY(bridge_iflist) next; /* next in list */ 388 struct bridge_softc *bridge_sc; 389 struct bstp_port *bif_stp; /* STP port state */ 390 struct brl_head bif_brlin; /* input rules */ 391 struct brl_head bif_brlout; /* output rules */ 392 struct ifnet *ifp; /* member interface */ 393 u_int32_t bif_flags; /* member flags */ 394 }; 395 #define bif_state bif_stp->bp_state 396 397 #define SAME_BRIDGE(_bp1, _bp2) \ 398 (_bp1 && _bp2 && ((struct bridge_iflist *)_bp1)->bridge_sc == \ 399 ((struct bridge_iflist *)_bp2)->bridge_sc) 400 401 /* 402 * Bridge route node 403 */ 404 struct bridge_rtnode { 405 LIST_ENTRY(bridge_rtnode) brt_next; /* next in list */ 406 struct ifnet *brt_if; /* destination ifs */ 407 u_int8_t brt_flags; /* address flags */ 408 u_int8_t brt_age; /* age counter */ 409 struct ether_addr brt_addr; /* dst addr */ 410 union sockaddr_union brt_tunnel; /* tunnel endpoint */ 411 }; 412 413 #ifndef BRIDGE_RTABLE_SIZE 414 #define BRIDGE_RTABLE_SIZE 1024 415 #endif 416 #define BRIDGE_RTABLE_MASK (BRIDGE_RTABLE_SIZE - 1) 417 418 /* 419 * Software state for each bridge 420 */ 421 struct bridge_softc { 422 struct ifnet sc_if; /* the interface */ 423 LIST_ENTRY(bridge_softc) sc_list; /* all bridges */ 424 struct bridge_iflist *sc_root_port; 425 u_int32_t sc_brtmax; /* max # addresses */ 426 u_int32_t sc_brtcnt; /* current # addrs */ 427 int sc_brttimeout; /* timeout ticks */ 428 u_int32_t sc_hashkey; /* hash key */ 429 struct timeout sc_brtimeout; /* timeout state */ 430 struct bstp_state *sc_stp; /* stp state */ 431 TAILQ_HEAD(, bridge_iflist) sc_iflist; /* interface list */ 432 TAILQ_HEAD(, bridge_iflist) sc_spanlist; /* span ports */ 433 LIST_HEAD(, bridge_rtnode) sc_rts[BRIDGE_RTABLE_SIZE]; /* hash table */ 434 }; 435 436 extern const u_int8_t bstp_etheraddr[]; 437 438 void bridge_ifdetach(struct ifnet *); 439 struct mbuf *bridge_input(struct ifnet *, struct ether_header *, 440 struct mbuf *); 441 int bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *, 442 struct rtentry *); 443 void bridge_update(struct ifnet *, struct ether_addr *, int); 444 void bridge_rtdelete(struct bridge_softc *, struct ifnet *, int); 445 void bridge_rtagenode(struct ifnet *, int); 446 struct sockaddr *bridge_tunnel(struct mbuf *); 447 struct sockaddr *bridge_tunneltag(struct mbuf *, int); 448 void bridge_tunneluntag(struct mbuf *); 449 450 struct bstp_state *bstp_create(struct ifnet *); 451 void bstp_destroy(struct bstp_state *); 452 void bstp_initialization(struct bstp_state *); 453 void bstp_stop(struct bstp_state *); 454 int bstp_ioctl(struct ifnet *, u_long, caddr_t); 455 struct bstp_port *bstp_add(struct bstp_state *, struct ifnet *); 456 void bstp_delete(struct bstp_port *); 457 struct mbuf *bstp_input(struct bstp_state *, struct bstp_port *, 458 struct ether_header *, struct mbuf *); 459 void bstp_ifstate(void *); 460 u_int8_t bstp_getstate(struct bstp_state *, struct bstp_port *); 461 void bstp_ifsflags(struct bstp_port *, u_int); 462 #endif /* _KERNEL */ 463 #endif /* _NET_IF_BRIDGE_H_ */ 464