/* $OpenBSD: if_etherbridge.h,v 1.3 2021/02/26 01:28:51 dlg Exp $ */ /* * Copyright (c) 2018, 2021 David Gwynne * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _NET_ETHERBRIDGE_H_ #define _NET_ETHERBRIDGE_H_ #define ETHERBRIDGE_TABLE_BITS 8 #define ETHERBRIDGE_TABLE_SIZE (1U << ETHERBRIDGE_TABLE_BITS) #define ETHERBRIDGE_TABLE_MASK (ETHERBRIDGE_TABLE_SIZE - 1) struct etherbridge_ops { int (*eb_op_port_eq)(void *, void *, void *); void *(*eb_op_port_take)(void *, void *); void (*eb_op_port_rele)(void *, void *); size_t (*eb_op_port_ifname)(void *, char *, size_t, void *); void (*eb_op_port_sa)(void *, struct sockaddr_storage *, void *); }; struct etherbridge; struct eb_entry { SMR_TAILQ_ENTRY(eb_entry) ebe_lentry; union { RBT_ENTRY(eb_entry) _ebe_tentry; TAILQ_ENTRY(eb_entry) _ebe_qentry; } _ebe_entries; #define ebe_tentry _ebe_entries._ebe_tentry #define ebe_qentry _ebe_entries._ebe_qentry uint64_t ebe_addr; void *ebe_port; unsigned int ebe_type; #define EBE_DYNAMIC 0x0 #define EBE_STATIC 0x1 #define EBE_DEAD 0xdead time_t ebe_age; struct etherbridge *ebe_etherbridge; struct refcnt ebe_refs; struct smr_entry ebe_smr_entry; }; SMR_TAILQ_HEAD(eb_list, eb_entry); RBT_HEAD(eb_tree, eb_entry); TAILQ_HEAD(eb_queue, eb_entry); struct etherbridge { const char *eb_name; const struct etherbridge_ops *eb_ops; void *eb_cookie; struct mutex eb_lock; unsigned int eb_num; unsigned int eb_max; int eb_max_age; /* seconds */ struct timeout eb_tmo_age; struct eb_list *eb_table; struct eb_tree eb_tree; }; int etherbridge_init(struct etherbridge *, const char *, const struct etherbridge_ops *, void *); int etherbridge_up(struct etherbridge *); int etherbridge_down(struct etherbridge *); void etherbridge_destroy(struct etherbridge *); void etherbridge_map(struct etherbridge *, void *, uint64_t); void etherbridge_map_ea(struct etherbridge *, void *, const struct ether_addr *); void *etherbridge_resolve(struct etherbridge *, uint64_t); void *etherbridge_resolve_ea(struct etherbridge *, const struct ether_addr *); void etherbridge_detach_port(struct etherbridge *, void *); /* ioctl support */ int etherbridge_set_max(struct etherbridge *, struct ifbrparam *); int etherbridge_get_max(struct etherbridge *, struct ifbrparam *); int etherbridge_set_tmo(struct etherbridge *, struct ifbrparam *); int etherbridge_get_tmo(struct etherbridge *, struct ifbrparam *); int etherbridge_rtfind(struct etherbridge *, struct ifbaconf *); int etherbridge_add_addr(struct etherbridge *, void *, const struct ether_addr *, unsigned int); int etherbridge_del_addr(struct etherbridge *, const struct ether_addr *); void etherbridge_flush(struct etherbridge *, uint32_t); static inline unsigned int etherbridge_num(const struct etherbridge *eb) { return (eb->eb_num); } #endif /* _NET_ETHERBRIDGE_H_ */