root/sys/net/if_bridge.h
/*      $OpenBSD: if_bridge.h,v 1.77 2025/11/21 04:44:26 dlg Exp $      */

/*
 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
 * Copyright (c) 2006 Andrew Thompson (thompsa@FreeBSD.org)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Effort sponsored in part by the Defense Advanced Research Projects
 * Agency (DARPA) and Air Force Research Laboratory, Air Force
 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
 *
 */

#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

/*
 * Bridge control request: add/delete member interfaces.
 */
struct ifbreq {
        char            ifbr_name[IFNAMSIZ];    /* bridge ifs name */
        char            ifbr_ifsname[IFNAMSIZ]; /* member ifs name */
        u_int32_t       ifbr_ifsflags;          /* member ifs flags */
        u_int32_t       ifbr_portno;            /* member port number */
        u_int32_t       ifbr_protected;         /* protected domains */

        u_int8_t        ifbr_state;             /* member stp state */
        u_int8_t        ifbr_priority;          /* member stp priority */
        u_int16_t       ifbr_pvid;              /* member port vlan id */
        u_int32_t       ifbr_path_cost;         /* member stp path cost */
        u_int32_t       ifbr_stpflags;          /* member stp flags */
        u_int8_t        ifbr_proto;             /* member stp protocol */
        u_int8_t        ifbr_role;              /* member stp role */
        u_int32_t       ifbr_fwd_trans;         /* member stp fwd transitions */
        u_int64_t       ifbr_desg_bridge;       /* member stp designated bridge */
        u_int32_t       ifbr_desg_port;         /* member stp designated port */
        u_int64_t       ifbr_root_bridge;       /* member stp root bridge */
        u_int32_t       ifbr_root_cost;         /* member stp root cost */
        u_int32_t       ifbr_root_port;         /* member stp root port */
};

/* SIOCBRDGIFFLGS, SIOCBRDGIFFLGS */
#define IFBIF_LEARNING          0x0001  /* ifs can learn */
#define IFBIF_DISCOVER          0x0002  /* ifs sends packets w/unknown dest */
#define IFBIF_BLOCKNONIP        0x0004  /* ifs blocks non-IP/ARP in/out */
#define IFBIF_STP               0x0008  /* ifs participates in spanning tree */
#define IFBIF_BSTP_EDGE         0x0010  /* member stp edge port */
#define IFBIF_BSTP_AUTOEDGE     0x0020  /* member stp autoedge enabled */
#define IFBIF_BSTP_PTP          0x0040  /* member stp ptp */
#define IFBIF_BSTP_AUTOPTP      0x0080  /* member stp autoptp enabled */
#define IFBIF_SPAN              0x0100  /* ifs is a span port (ro) */
#define IFBIF_LOCAL             0x1000  /* local port in switch(4) */
#define IFBIF_LOCKED            0x2000  /* restrict rx src mac with fib */
#define IFBIF_PVLAN_PTAGS       0x4000  /* only use tags for primary pvlans */
#define IFBIF_RO_MASK           0x0f00  /* read only bits */

/* SIOCBRDGFLUSH */
#define IFBF_FLUSHDYN   0x0     /* flush dynamic addresses only */
#define IFBF_FLUSHALL   0x1     /* flush all addresses from cache */

/* port states */
#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

/*
 * Interface list structure
 */
struct ifbifconf {
        char            ifbic_name[IFNAMSIZ];   /* bridge ifs name */
        u_int32_t       ifbic_len;              /* buffer size */
        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
};

/*
 * Bridge address request
 */
struct ifbareq {
        char                    ifba_name[IFNAMSIZ];    /* bridge name */
        char                    ifba_ifsname[IFNAMSIZ]; /* destination ifs */
        u_int8_t                ifba_age;               /* address age */
        u_int8_t                ifba_flags;             /* address flags */
        struct ether_addr       ifba_dst;               /* destination addr */
        struct sockaddr_storage ifba_dstsa;             /* tunnel endpoint */
};

#define IFBAF_TYPEMASK          0x03            /* address type mask */
#define IFBAF_DYNAMIC           0x00            /* dynamically learned */
#define IFBAF_STATIC            0x01            /* static address */

struct ifbvareq;

struct ifbaconf {
        char                    ifbac_name[IFNAMSIZ];   /* bridge ifs name */
        u_int32_t               ifbac_len;              /* buffer size */
        union {
                caddr_t ifbacu_buf;                     /* buffer */
                struct ifbareq *ifbacu_req;             /* request pointer */
                struct ifbvareq *ifbacu_vreq;           /* request pointer */
        } 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;           /* cache size */
                int             ifbrpu_ctime;           /* cache time (sec) */
                u_int16_t       ifbrpu_prio;            /* bridge priority */
                u_int8_t        ifbrpu_hellotime;       /* hello time (sec) */
                u_int8_t        ifbrpu_fwddelay;        /* fwd delay (sec) */
                u_int8_t        ifbrpu_maxage;          /* max age (sec) */
                u_int8_t        ifbrpu_proto;           /* bridge protocol */
                u_int8_t        ifbrpu_txhc;            /* bpdu tx holdcount */
        } 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

/* Protocol versions */
#define BSTP_PROTO_ID           0x00
#define BSTP_PROTO_STP          0x00
#define BSTP_PROTO_RSTP         0x02
#define BSTP_PROTO_MAX          BSTP_PROTO_RSTP

/*
 * Bridge current operational parameters structure.
 */
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;
};

/*
 * Bridge mac rules
 */
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];    /* bridge ifs name */
        char                    ifbr_ifsname[IFNAMSIZ]; /* member ifs name */
        u_int8_t                ifbr_action;            /* disposition */
        u_int8_t                ifbr_flags;             /* flags */
        struct ether_addr       ifbr_src;               /* source mac */
        struct ether_addr       ifbr_dst;               /* destination mac */
        char                    ifbr_tagname[PF_TAG_NAME_SIZE]; /* pf tagname */
        struct ifbrarpf         ifbr_arpf;              /* arp filter */
};
#define BRL_ACTION_BLOCK        0x01                    /* block frame */
#define BRL_ACTION_PASS         0x02                    /* pass frame */
#define BRL_FLAG_IN             0x08                    /* input rule */
#define BRL_FLAG_OUT            0x04                    /* output rule */
#define BRL_FLAG_SRCVALID       0x02                    /* src valid */
#define BRL_FLAG_DSTVALID       0x01                    /* dst valid */

struct ifbrlconf {
        char            ifbrl_name[IFNAMSIZ];   /* bridge ifs name */
        char            ifbrl_ifsname[IFNAMSIZ];/* member ifs name */
        u_int32_t       ifbrl_len;              /* buffer size */
        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];   /* bridge name */
        char                    ifbva_ifsname[IFNAMSIZ];        /* destination ifs */
        time_t                  ifbva_created;          /* monotime */
        time_t                  ifbva_used;             /* monotime */
        unsigned int            ifbva_flags;            /* address flags */
        uint16_t                ifbva_vid;              /* vlan */
        struct ether_addr       ifbva_dst;              /* destination addr */
        struct sockaddr_storage ifbva_dstsa;            /* tunnel endpoint */
};

struct ifbrvidmap {
        char                    ifbrvm_name[IFNAMSIZ];
        char                    ifbrvm_ifsname[IFNAMSIZ];
        unsigned int            ifbrvm_op;
#define IFBRVM_OP_SET                   0x0     /* kernel = ifbrvm_map */
#define IFBRVM_OP_OR                    0x1     /* kernel |= ifbrvm_map */
#define IFBRVM_OP_ANDNOT                0x2     /* kernel &= ~ifbrvm_map */
        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       /* for searching */
#define IFBRPV_T_ISOLATED               2
#define IFBRPV_T_COMMUNITY              3
        unsigned int            ifbrpv_gen;
};

#ifdef _KERNEL

#include <sys/mutex.h>

/* STP port flags */
#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

/* BPDU priority */
#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

/* BPDU flags */
#define BSTP_PDU_PRMASK         0x0c            /* Port Role */
#define BSTP_PDU_PRSHIFT        2               /* Port Role offset */
#define BSTP_PDU_F_UNKN         0x00            /* Unknown port    (00) */
#define BSTP_PDU_F_ALT          0x01            /* Alt/Backup port (01) */
#define BSTP_PDU_F_ROOT         0x02            /* Root port       (10) */
#define BSTP_PDU_F_DESG         0x03            /* Designated port (11) */

#define BSTP_PDU_STPMASK        0x81            /* strip unused STP flags */
#define BSTP_PDU_RSTPMASK       0x7f            /* strip unused RSTP flags */
#define BSTP_PDU_F_TC           0x01            /* Topology change */
#define BSTP_PDU_F_P            0x02            /* Proposal flag */
#define BSTP_PDU_F_L            0x10            /* Learning flag */
#define BSTP_PDU_F_F            0x20            /* Forwarding flag */
#define BSTP_PDU_F_A            0x40            /* Agreement flag */
#define BSTP_PDU_F_TCA          0x80            /* Topology change ack */

/*
 * Bridge filtering rules
 */
SIMPLEQ_HEAD(brl_head, brl_node);

struct brl_node {
        SIMPLEQ_ENTRY(brl_node) brl_next;       /* next rule */
        struct ether_addr       brl_src;        /* source mac address */
        struct ether_addr       brl_dst;        /* destination mac address */
        u_int16_t               brl_tag;        /* pf tag ID */
        u_int8_t                brl_action;     /* what to do with match */
        u_int8_t                brl_flags;      /* comparison flags */
        struct ifbrarpf         brl_arpf;       /* arp filter */
};

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;     /* parent interface index */
        struct bstp_state       *bp_bs;
        struct task             bp_ltask;       /* if linkstate hook */
        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;
};

/*
 * Software state for each bridge STP.
 */
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;         /* stp timeout */
        struct bstp_timer       bs_link_timer;
        struct timeval          bs_last_tc_time;
        LIST_HEAD(, bstp_port)  bs_bplist;
};

/*
 * Bridge interface list
 *
 *  Locks used to protect struct members in this file:
 *      I       immutable after creation
 *      k       kernel lock
 */
struct bridge_iflist {
        SMR_SLIST_ENTRY(bridge_iflist)  bif_next;       /* [k] next in list */
        struct bridge_softc             *bridge_sc;     /* [I] sc backpointer */
        struct bstp_port                *bif_stp;       /* [I] STP port state */
        struct brl_head                 bif_brlin;      /* [k] input rules */
        struct brl_head                 bif_brlout;     /* [k] output rules */
        struct ifnet                    *ifp;           /* [I] net interface */
        u_int32_t                       bif_flags;      /* member flags */
        u_int32_t                       bif_protected;  /* protected domains */
        struct task                     bif_dtask;
};
#define bif_state                       bif_stp->bp_state

/*
 * XXX ip_ipsp.h's sockaddr_union should be converted to sockaddr *
 * passing with correct sa_len, then a good approach for cleaning this
 * will become more clear.
 */
union brsockaddr_union {
        struct sockaddr         sa;
        struct sockaddr_in      sin;
        struct sockaddr_in6     sin6;
};

/*
 * Bridge tunnel tagging
 */
struct bridge_tunneltag {
        union brsockaddr_union          brtag_peer;
        union brsockaddr_union          brtag_local;
        u_int32_t                       brtag_id;
};

/*
 * Bridge route node
 */
struct bridge_rtnode {
        LIST_ENTRY(bridge_rtnode)       brt_next;       /* next in list */
        unsigned int                    brt_ifidx;      /* destination ifs */
        u_int8_t                        brt_flags;      /* address flags */
        u_int8_t                        brt_age;        /* age counter */
        struct ether_addr               brt_addr;       /* dst addr */
        struct bridge_tunneltag         brt_tunnel;     /* tunnel endpoint */
};
#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)

/*
 * Software state for each bridge
 *
 *  Locks used to protect struct members in this file:
 *      I       immutable after creation
 *      m       per-softc mutex
 *      k       kernel lock
 */
struct bridge_softc {
        struct ifnet                    sc_if;  /* the interface */
        uint32_t                        sc_brtmax;      /* [m] max # addresses */
        uint32_t                        sc_brtcnt;      /* [m] current # addrs */
        int                             sc_brttimeout;  /* timeout ticks */
        uint64_t                        sc_hashkey[2];  /* [I] siphash key */
        struct timeout                  sc_brtimeout;   /* timeout state */
        struct bstp_state               *sc_stp;        /* stp state */
        SMR_SLIST_HEAD(, bridge_iflist) sc_iflist;      /* [k] interface list */
        SMR_SLIST_HEAD(, bridge_iflist) sc_spanlist;    /* [k] span ports */
        struct mutex                    sc_mtx;         /* mutex */
        LIST_HEAD(, bridge_rtnode)      sc_rts[BRIDGE_RTABLE_SIZE];     /* [m] hash table */
};

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 /* _KERNEL */
#endif /* _NET_IF_BRIDGE_H_ */