#ifndef _NET_IF_BRIDGE_H_
#define _NET_IF_BRIDGE_H_
#include <sys/smr.h>
#include <sys/timeout.h>
#include <net/pfvar.h>
#define IFBR_PVID_NULL EVL_VLID_NULL
#define IFBR_PVID_MIN EVL_VLID_MIN
#define IFBR_PVID_MAX EVL_VLID_MAX
#define IFBR_PVID_NONE 0xffff
#define IFBR_PVID_DECLINE 0xfffe
struct ifbreq {
char ifbr_name[IFNAMSIZ];
char ifbr_ifsname[IFNAMSIZ];
u_int32_t ifbr_ifsflags;
u_int32_t ifbr_portno;
u_int32_t ifbr_protected;
u_int8_t ifbr_state;
u_int8_t ifbr_priority;
u_int16_t ifbr_pvid;
u_int32_t ifbr_path_cost;
u_int32_t ifbr_stpflags;
u_int8_t ifbr_proto;
u_int8_t ifbr_role;
u_int32_t ifbr_fwd_trans;
u_int64_t ifbr_desg_bridge;
u_int32_t ifbr_desg_port;
u_int64_t ifbr_root_bridge;
u_int32_t ifbr_root_cost;
u_int32_t ifbr_root_port;
};
#define IFBIF_LEARNING 0x0001
#define IFBIF_DISCOVER 0x0002
#define IFBIF_BLOCKNONIP 0x0004
#define IFBIF_STP 0x0008
#define IFBIF_BSTP_EDGE 0x0010
#define IFBIF_BSTP_AUTOEDGE 0x0020
#define IFBIF_BSTP_PTP 0x0040
#define IFBIF_BSTP_AUTOPTP 0x0080
#define IFBIF_SPAN 0x0100
#define IFBIF_LOCAL 0x1000
#define IFBIF_LOCKED 0x2000
#define IFBIF_PVLAN_PTAGS 0x4000
#define IFBIF_RO_MASK 0x0f00
#define IFBF_FLUSHDYN 0x0
#define IFBF_FLUSHALL 0x1
#define BSTP_IFSTATE_DISABLED 0
#define BSTP_IFSTATE_LISTENING 1
#define BSTP_IFSTATE_LEARNING 2
#define BSTP_IFSTATE_FORWARDING 3
#define BSTP_IFSTATE_BLOCKING 4
#define BSTP_IFSTATE_DISCARDING 5
#define BSTP_TCSTATE_ACTIVE 1
#define BSTP_TCSTATE_DETECTED 2
#define BSTP_TCSTATE_INACTIVE 3
#define BSTP_TCSTATE_LEARNING 4
#define BSTP_TCSTATE_PROPAG 5
#define BSTP_TCSTATE_ACK 6
#define BSTP_TCSTATE_TC 7
#define BSTP_TCSTATE_TCN 8
#define BSTP_ROLE_DISABLED 0
#define BSTP_ROLE_ROOT 1
#define BSTP_ROLE_DESIGNATED 2
#define BSTP_ROLE_ALTERNATE 3
#define BSTP_ROLE_BACKUP 4
struct ifbifconf {
char ifbic_name[IFNAMSIZ];
u_int32_t ifbic_len;
union {
caddr_t ifbicu_buf;
struct ifbreq *ifbicu_req;
} ifbic_ifbicu;
#define ifbic_buf ifbic_ifbicu.ifbicu_buf
#define ifbic_req ifbic_ifbicu.ifbicu_req
};
struct ifbareq {
char ifba_name[IFNAMSIZ];
char ifba_ifsname[IFNAMSIZ];
u_int8_t ifba_age;
u_int8_t ifba_flags;
struct ether_addr ifba_dst;
struct sockaddr_storage ifba_dstsa;
};
#define IFBAF_TYPEMASK 0x03
#define IFBAF_DYNAMIC 0x00
#define IFBAF_STATIC 0x01
struct ifbvareq;
struct ifbaconf {
char ifbac_name[IFNAMSIZ];
u_int32_t ifbac_len;
union {
caddr_t ifbacu_buf;
struct ifbareq *ifbacu_req;
struct ifbvareq *ifbacu_vreq;
} ifbac_ifbacu;
#define ifbac_buf ifbac_ifbacu.ifbacu_buf
#define ifbac_req ifbac_ifbacu.ifbacu_req
#define ifbac_vreq ifbac_ifbacu.ifbacu_vreq
};
struct ifbrparam {
char ifbrp_name[IFNAMSIZ];
union {
u_int32_t ifbrpu_csize;
int ifbrpu_ctime;
u_int16_t ifbrpu_prio;
u_int8_t ifbrpu_hellotime;
u_int8_t ifbrpu_fwddelay;
u_int8_t ifbrpu_maxage;
u_int8_t ifbrpu_proto;
u_int8_t ifbrpu_txhc;
} ifbrp_ifbrpu;
};
#define ifbrp_csize ifbrp_ifbrpu.ifbrpu_csize
#define ifbrp_ctime ifbrp_ifbrpu.ifbrpu_ctime
#define ifbrp_prio ifbrp_ifbrpu.ifbrpu_prio
#define ifbrp_proto ifbrp_ifbrpu.ifbrpu_proto
#define ifbrp_txhc ifbrp_ifbrpu.ifbrpu_txhc
#define ifbrp_hellotime ifbrp_ifbrpu.ifbrpu_hellotime
#define ifbrp_fwddelay ifbrp_ifbrpu.ifbrpu_fwddelay
#define ifbrp_maxage ifbrp_ifbrpu.ifbrpu_maxage
#define BSTP_PROTO_ID 0x00
#define BSTP_PROTO_STP 0x00
#define BSTP_PROTO_RSTP 0x02
#define BSTP_PROTO_MAX BSTP_PROTO_RSTP
struct ifbropreq {
char ifbop_name[IFNAMSIZ];
u_int8_t ifbop_holdcount;
u_int8_t ifbop_maxage;
u_int8_t ifbop_hellotime;
u_int8_t ifbop_fwddelay;
u_int8_t ifbop_protocol;
u_int16_t ifbop_priority;
u_int64_t ifbop_root_bridge;
u_int16_t ifbop_root_port;
u_int32_t ifbop_root_path_cost;
u_int64_t ifbop_desg_bridge;
struct timeval ifbop_last_tc_time;
};
struct ifbrarpf {
u_int16_t brla_flags;
u_int16_t brla_op;
struct ether_addr brla_sha;
struct in_addr brla_spa;
struct ether_addr brla_tha;
struct in_addr brla_tpa;
};
#define BRLA_ARP 0x01
#define BRLA_RARP 0x02
#define BRLA_SHA 0x10
#define BRLA_SPA 0x20
#define BRLA_THA 0x40
#define BRLA_TPA 0x80
struct ifbrlreq {
char ifbr_name[IFNAMSIZ];
char ifbr_ifsname[IFNAMSIZ];
u_int8_t ifbr_action;
u_int8_t ifbr_flags;
struct ether_addr ifbr_src;
struct ether_addr ifbr_dst;
char ifbr_tagname[PF_TAG_NAME_SIZE];
struct ifbrarpf ifbr_arpf;
};
#define BRL_ACTION_BLOCK 0x01
#define BRL_ACTION_PASS 0x02
#define BRL_FLAG_IN 0x08
#define BRL_FLAG_OUT 0x04
#define BRL_FLAG_SRCVALID 0x02
#define BRL_FLAG_DSTVALID 0x01
struct ifbrlconf {
char ifbrl_name[IFNAMSIZ];
char ifbrl_ifsname[IFNAMSIZ];
u_int32_t ifbrl_len;
union {
caddr_t ifbrlu_buf;
struct ifbrlreq *ifbrlu_req;
} ifbrl_ifbrlu;
#define ifbrl_buf ifbrl_ifbrlu.ifbrlu_buf
#define ifbrl_req ifbrl_ifbrlu.ifbrlu_req
};
struct ifbvareq {
char ifbva_name[IFNAMSIZ];
char ifbva_ifsname[IFNAMSIZ];
time_t ifbva_created;
time_t ifbva_used;
unsigned int ifbva_flags;
uint16_t ifbva_vid;
struct ether_addr ifbva_dst;
struct sockaddr_storage ifbva_dstsa;
};
struct ifbrvidmap {
char ifbrvm_name[IFNAMSIZ];
char ifbrvm_ifsname[IFNAMSIZ];
unsigned int ifbrvm_op;
#define IFBRVM_OP_SET 0x0
#define IFBRVM_OP_OR 0x1
#define IFBRVM_OP_ANDNOT 0x2
unsigned int ifbrvm_gen;
uint8_t ifbrvm_map[512];
};
struct ifbrpvlan {
char ifbrpv_name[IFNAMSIZ];
uint16_t ifbrpv_primary;
uint16_t ifbrpv_secondary;
unsigned int ifbrpv_type;
#define IFBRPV_T_PRIMARY 0
#define IFBRPV_T_SECONDARY 1
#define IFBRPV_T_ISOLATED 2
#define IFBRPV_T_COMMUNITY 3
unsigned int ifbrpv_gen;
};
#ifdef _KERNEL
#include <sys/mutex.h>
#define BSTP_PORT_CANMIGRATE 0x0001
#define BSTP_PORT_NEWINFO 0x0002
#define BSTP_PORT_DISPUTED 0x0004
#define BSTP_PORT_ADMCOST 0x0008
#define BSTP_PORT_AUTOEDGE 0x0010
#define BSTP_PORT_AUTOPTP 0x0020
#define BSTP_PDU_SUPERIOR 1
#define BSTP_PDU_REPEATED 2
#define BSTP_PDU_INFERIOR 3
#define BSTP_PDU_INFERIORALT 4
#define BSTP_PDU_OTHER 5
#define BSTP_PDU_PRMASK 0x0c
#define BSTP_PDU_PRSHIFT 2
#define BSTP_PDU_F_UNKN 0x00
#define BSTP_PDU_F_ALT 0x01
#define BSTP_PDU_F_ROOT 0x02
#define BSTP_PDU_F_DESG 0x03
#define BSTP_PDU_STPMASK 0x81
#define BSTP_PDU_RSTPMASK 0x7f
#define BSTP_PDU_F_TC 0x01
#define BSTP_PDU_F_P 0x02
#define BSTP_PDU_F_L 0x10
#define BSTP_PDU_F_F 0x20
#define BSTP_PDU_F_A 0x40
#define BSTP_PDU_F_TCA 0x80
SIMPLEQ_HEAD(brl_head, brl_node);
struct brl_node {
SIMPLEQ_ENTRY(brl_node) brl_next;
struct ether_addr brl_src;
struct ether_addr brl_dst;
u_int16_t brl_tag;
u_int8_t brl_action;
u_int8_t brl_flags;
struct ifbrarpf brl_arpf;
};
struct bstp_timer {
u_int16_t active;
u_int16_t value;
u_int32_t latched;
};
struct bstp_pri_vector {
u_int64_t pv_root_id;
u_int32_t pv_cost;
u_int64_t pv_dbridge_id;
u_int16_t pv_dport_id;
u_int16_t pv_port_id;
};
struct bstp_config_unit {
struct bstp_pri_vector cu_pv;
u_int16_t cu_message_age;
u_int16_t cu_max_age;
u_int16_t cu_forward_delay;
u_int16_t cu_hello_time;
u_int8_t cu_message_type;
u_int8_t cu_topology_change_ack;
u_int8_t cu_topology_change;
u_int8_t cu_proposal;
u_int8_t cu_agree;
u_int8_t cu_learning;
u_int8_t cu_forwarding;
u_int8_t cu_role;
};
struct bstp_tcn_unit {
u_int8_t tu_message_type;
};
struct bstp_port {
LIST_ENTRY(bstp_port) bp_next;
unsigned int bp_ifindex;
struct bstp_state *bp_bs;
struct task bp_ltask;
u_int8_t bp_active;
u_int8_t bp_protover;
u_int32_t bp_flags;
u_int32_t bp_path_cost;
u_int16_t bp_port_msg_age;
u_int16_t bp_port_max_age;
u_int16_t bp_port_fdelay;
u_int16_t bp_port_htime;
u_int16_t bp_desg_msg_age;
u_int16_t bp_desg_max_age;
u_int16_t bp_desg_fdelay;
u_int16_t bp_desg_htime;
struct bstp_timer bp_edge_delay_timer;
struct bstp_timer bp_forward_delay_timer;
struct bstp_timer bp_hello_timer;
struct bstp_timer bp_message_age_timer;
struct bstp_timer bp_migrate_delay_timer;
struct bstp_timer bp_recent_backup_timer;
struct bstp_timer bp_recent_root_timer;
struct bstp_timer bp_tc_timer;
struct bstp_config_unit bp_msg_cu;
struct bstp_pri_vector bp_desg_pv;
struct bstp_pri_vector bp_port_pv;
u_int16_t bp_port_id;
u_int8_t bp_state;
u_int8_t bp_tcstate;
u_int8_t bp_role;
u_int8_t bp_infois;
u_int8_t bp_tc_ack;
u_int8_t bp_tc_prop;
u_int8_t bp_fdbflush;
u_int8_t bp_priority;
u_int8_t bp_ptp_link;
u_int8_t bp_agree;
u_int8_t bp_agreed;
u_int8_t bp_sync;
u_int8_t bp_synced;
u_int8_t bp_proposing;
u_int8_t bp_proposed;
u_int8_t bp_operedge;
u_int8_t bp_reroot;
u_int8_t bp_rcvdtc;
u_int8_t bp_rcvdtca;
u_int8_t bp_rcvdtcn;
u_int32_t bp_forward_transitions;
u_int8_t bp_txcount;
};
struct bstp_state {
unsigned int bs_ifindex;
struct bstp_pri_vector bs_bridge_pv;
struct bstp_pri_vector bs_root_pv;
struct bstp_port *bs_root_port;
u_int8_t bs_protover;
u_int16_t bs_migration_delay;
u_int16_t bs_edge_delay;
u_int16_t bs_bridge_max_age;
u_int16_t bs_bridge_fdelay;
u_int16_t bs_bridge_htime;
u_int16_t bs_root_msg_age;
u_int16_t bs_root_max_age;
u_int16_t bs_root_fdelay;
u_int16_t bs_root_htime;
u_int16_t bs_hold_time;
u_int16_t bs_bridge_priority;
u_int8_t bs_txholdcount;
u_int8_t bs_allsynced;
struct timeout bs_bstptimeout;
struct bstp_timer bs_link_timer;
struct timeval bs_last_tc_time;
LIST_HEAD(, bstp_port) bs_bplist;
};
struct bridge_iflist {
SMR_SLIST_ENTRY(bridge_iflist) bif_next;
struct bridge_softc *bridge_sc;
struct bstp_port *bif_stp;
struct brl_head bif_brlin;
struct brl_head bif_brlout;
struct ifnet *ifp;
u_int32_t bif_flags;
u_int32_t bif_protected;
struct task bif_dtask;
};
#define bif_state bif_stp->bp_state
union brsockaddr_union {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
};
struct bridge_tunneltag {
union brsockaddr_union brtag_peer;
union brsockaddr_union brtag_local;
u_int32_t brtag_id;
};
struct bridge_rtnode {
LIST_ENTRY(bridge_rtnode) brt_next;
unsigned int brt_ifidx;
u_int8_t brt_flags;
u_int8_t brt_age;
struct ether_addr brt_addr;
struct bridge_tunneltag brt_tunnel;
};
#define brt_family brt_tunnel.brtag_peer.sa.sa_family
#ifndef BRIDGE_RTABLE_SIZE
#define BRIDGE_RTABLE_SIZE 1024
#endif
#define BRIDGE_RTABLE_MASK (BRIDGE_RTABLE_SIZE - 1)
struct bridge_softc {
struct ifnet sc_if;
uint32_t sc_brtmax;
uint32_t sc_brtcnt;
int sc_brttimeout;
uint64_t sc_hashkey[2];
struct timeout sc_brtimeout;
struct bstp_state *sc_stp;
SMR_SLIST_HEAD(, bridge_iflist) sc_iflist;
SMR_SLIST_HEAD(, bridge_iflist) sc_spanlist;
struct mutex sc_mtx;
LIST_HEAD(, bridge_rtnode) sc_rts[BRIDGE_RTABLE_SIZE];
};
extern const u_int8_t bstp_etheraddr[];
struct llc;
int bridge_enqueue(struct ifnet *, struct mbuf *);
void bridge_update(struct ifnet *, struct ether_addr *, int);
void bridge_rtdelete(struct bridge_softc *, struct ifnet *, int);
void bridge_rtagenode(struct ifnet *, int);
struct bridge_tunneltag *bridge_tunnel(struct mbuf *);
struct bridge_tunneltag *bridge_tunneltag(struct mbuf *);
void bridge_tunneluntag(struct mbuf *);
void bridge_copyaddr(struct sockaddr *, struct sockaddr *);
void bridge_copytag(struct bridge_tunneltag *, struct bridge_tunneltag *);
struct bstp_state *bstp_create(void);
void bstp_enable(struct bstp_state *bs, unsigned int);
void bstp_disable(struct bstp_state *bs);
void bstp_destroy(struct bstp_state *);
void bstp_initialization(struct bstp_state *);
void bstp_stop(struct bstp_state *);
int bstp_ioctl(struct ifnet *, u_long, caddr_t);
struct bstp_port *bstp_add(struct bstp_state *, struct ifnet *);
void bstp_delete(struct bstp_port *);
struct mbuf *bstp_input(struct bstp_state *, struct bstp_port *,
struct ether_header *, struct mbuf *);
void bstp_ifstate(void *);
u_int8_t bstp_getstate(struct bstp_state *, struct bstp_port *);
void bstp_ifsflags(struct bstp_port *, u_int);
int bridgectl_ioctl(struct ifnet *, u_long, caddr_t);
int bridge_rtupdate(struct bridge_softc *,
struct ether_addr *, struct ifnet *, int, u_int8_t, struct mbuf *);
unsigned int bridge_rtlookup(struct ifnet *,
struct ether_addr *, struct mbuf *);
void bridge_rtflush(struct bridge_softc *, int);
void bridge_rtage(void *);
u_int8_t bridge_filterrule(struct brl_head *, struct ether_header *,
struct mbuf *);
void bridge_flushrule(struct bridge_iflist *);
void bridge_fragment(struct ifnet *, struct ifnet *, struct ether_header *,
struct mbuf *);
struct bridge_iflist *bridge_getbif(struct ifnet *);
int bridge_findbif(struct bridge_softc *, const char *,
struct bridge_iflist **);
#endif
#endif