#ifndef _NET_IF_VAR_H_
#define _NET_IF_VAR_H_
#ifdef _KERNEL
#include <sys/queue.h>
#include <sys/mbuf.h>
#include <sys/smr.h>
#include <sys/refcnt.h>
#include <sys/task.h>
#include <sys/timeout.h>
#include <net/ifq.h>
#include <net/route.h>
struct rtentry;
struct ifnet;
struct task;
struct cpumem;
struct netstack {
struct mbuf_list ns_input;
struct mbuf_list ns_proto;
struct route ns_route;
struct mbuf_list ns_tcp_ml;
struct mbuf_list ns_tcp6_ml;
};
struct if_clone {
LIST_ENTRY(if_clone) ifc_list;
const char *ifc_name;
size_t ifc_namelen;
int (*ifc_create)(struct if_clone *, int);
int (*ifc_destroy)(struct ifnet *);
};
#define IF_CLONE_INITIALIZER(name, create, destroy) \
{ \
.ifc_list = { NULL, NULL }, \
.ifc_name = name, \
.ifc_namelen = sizeof(name) - 1, \
.ifc_create = create, \
.ifc_destroy = destroy, \
}
enum if_counters {
ifc_ipackets,
ifc_ierrors,
ifc_opackets,
ifc_oerrors,
ifc_collisions,
ifc_ibytes,
ifc_obytes,
ifc_imcasts,
ifc_omcasts,
ifc_iqdrops,
ifc_oqdrops,
ifc_noproto,
ifc_ncounters
};
TAILQ_HEAD(ifnet_head, ifnet);
struct carp_softc;
SMR_LIST_HEAD(carp_iflist, carp_softc);
struct ifnet {
void *if_softc;
struct refcnt if_refcnt;
TAILQ_ENTRY(ifnet) if_list;
TAILQ_ENTRY(ifnet) if_tmplist;
TAILQ_HEAD(, ifaddr) if_addrlist;
TAILQ_HEAD(, ifmaddr) if_maddrlist;
TAILQ_HEAD(, ifg_list) if_groups;
struct rwlock if_maddrlock;
struct task_list if_addrhooks;
struct task_list if_linkstatehooks;
struct task_list if_detachhooks;
void (*if_rtrequest)(struct ifnet *, int, struct rtentry *);
char if_xname[IFNAMSIZ];
int if_pcount;
unsigned int if_bridgeidx;
caddr_t if_bpf;
caddr_t if_mcast;
caddr_t if_mcast6;
caddr_t if_pf_kif;
union {
struct carp_iflist carp_s;
unsigned int carp_idx;
} if_carp_ptr;
#define if_carp if_carp_ptr.carp_s
#define if_carpdevidx if_carp_ptr.carp_idx
unsigned int if_index;
short if_timer;
unsigned short if_flags;
int if_xflags;
u_char if_type;
u_char if_addrlen;
u_char if_hdrlen;
u_char if_link_state;
uint32_t if_mtu;
uint32_t if_metric;
uint64_t if_baudrate;
uint32_t if_capabilities;
uint32_t if_rdomain;
struct timeval if_lastchange;
uint64_t if_data_counters[ifc_ncounters];
struct cpumem *if_counters;
uint32_t if_hardmtu;
char if_description[IFDESCRSIZE];
u_short if_rtlabelid;
uint8_t if_priority;
uint8_t if_llprio;
struct timeout if_slowtimo;
struct task if_watchdogtask;
struct task if_linkstatetask;
void (*if_input)(struct ifnet *, struct mbuf *, struct netstack *);
int (*if_bpf_mtap)(caddr_t, const struct mbuf *, u_int);
int (*if_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
int (*if_ll_output)(struct ifnet *, struct mbuf *,
struct sockaddr *, struct rtentry *);
int (*if_enqueue)(struct ifnet *, struct mbuf *);
void (*if_start)(struct ifnet *);
int (*if_ioctl)(struct ifnet *, u_long, caddr_t);
void (*if_watchdog)(struct ifnet *);
int (*if_wol)(struct ifnet *, int);
struct ifqueue if_snd;
struct ifqueue **if_ifqs;
void (*if_qstart)(struct ifqueue *);
unsigned int if_nifqs;
unsigned int if_txmit;
struct ifiqueue if_rcv;
struct ifiqueue **if_iqs;
unsigned int if_niqs;
struct sockaddr_dl *if_sadl;
struct nd_ifinfo *if_nd;
};
#define if_ipackets if_data_counters[ifc_ipackets]
#define if_ierrors if_data_counters[ifc_ierrors]
#define if_opackets if_data_counters[ifc_opackets]
#define if_oerrors if_data_counters[ifc_oerrors]
#define if_collisions if_data_counters[ifc_collisions]
#define if_ibytes if_data_counters[ifc_ibytes]
#define if_obytes if_data_counters[ifc_obytes]
#define if_imcasts if_data_counters[ifc_imcasts]
#define if_omcasts if_data_counters[ifc_omcasts]
#define if_iqdrops if_data_counters[ifc_iqdrops]
#define if_oqdrops if_data_counters[ifc_oqdrops]
#define if_noproto if_data_counters[ifc_noproto]
struct ifaddr {
struct sockaddr *ifa_addr;
struct sockaddr *ifa_dstaddr;
#define ifa_broadaddr ifa_dstaddr
struct sockaddr *ifa_netmask;
struct ifnet *ifa_ifp;
TAILQ_ENTRY(ifaddr) ifa_list;
TAILQ_ENTRY(ifaddr) ifa_tmplist;
u_int ifa_flags;
struct refcnt ifa_refcnt;
int ifa_metric;
};
#define IFA_ROUTE 0x01
struct ifmaddr {
TAILQ_ENTRY(ifmaddr) ifma_list;
struct sockaddr *ifma_addr;
struct refcnt ifma_refcnt;
unsigned int ifma_ifidx;
};
struct ifg_group {
char ifg_group[IFNAMSIZ];
u_int ifg_refcnt;
caddr_t ifg_pf_kif;
int ifg_carp_demoted;
TAILQ_HEAD(, ifg_member) ifg_members;
TAILQ_ENTRY(ifg_group) ifg_next;
struct refcnt ifg_tmprefcnt;
TAILQ_ENTRY(ifg_group) ifg_tmplist;
};
struct ifg_member {
TAILQ_ENTRY(ifg_member) ifgm_next;
struct ifnet *ifgm_ifp;
};
struct ifg_list {
struct ifg_group *ifgl_group;
TAILQ_ENTRY(ifg_list) ifgl_next;
};
#define IFNET_SLOWTIMO 1
#define IF_TXMIT_MIN 1
#define IF_TXMIT_DEFAULT 16
#define IF_WIRED_DEFAULT_PRIORITY 0
#define IF_WIRELESS_DEFAULT_PRIORITY 4
#define IF_WWAN_DEFAULT_PRIORITY 6
#define IF_CARP_DEFAULT_PRIORITY 15
struct niqueue {
struct mbuf_queue ni_q;
u_int ni_isr;
};
#define NIQUEUE_INITIALIZER(_len, _isr) \
{ MBUF_QUEUE_INITIALIZER((_len), IPL_NET), (_isr) }
int niq_enqueue(struct niqueue *, struct mbuf *);
#define niq_dequeue(_q) mq_dequeue(&(_q)->ni_q)
#define niq_delist(_q, _ml) mq_delist(&(_q)->ni_q, (_ml))
#define niq_len(_q) mq_len(&(_q)->ni_q)
#define niq_drops(_q) mq_drops(&(_q)->ni_q)
#define sysctl_niq(_n, _l, _op, _olp, _np, _nl, _niq) \
sysctl_mq((_n), (_l), (_op), (_olp), (_np), (_nl), &(_niq)->ni_q)
extern struct rwlock if_tmplist_lock;
extern struct ifnet_head ifnetlist;
void if_start(struct ifnet *);
int if_enqueue(struct ifnet *, struct mbuf *);
int if_enqueue_ifq(struct ifnet *, struct mbuf *);
void if_input(struct ifnet *, struct mbuf_list *);
void if_vinput(struct ifnet *, struct mbuf *, struct netstack *);
void if_input_process(struct ifnet *, struct mbuf_list *, unsigned int);
void if_input_proto(struct ifnet *, struct mbuf *,
void (*)(struct ifnet *, struct mbuf *, struct netstack *),
struct netstack *);
int if_input_local(struct ifnet *, struct mbuf *, sa_family_t,
struct netstack *);
int if_output_ml(struct ifnet *, struct mbuf_list *,
struct sockaddr *, struct rtentry *);
int if_output_mq(struct ifnet *, struct mbuf_queue *, unsigned int *,
struct sockaddr *, struct rtentry *);
int if_output_tso(struct ifnet *, struct mbuf **, struct sockaddr *,
struct rtentry *, u_int);
int if_output_local(struct ifnet *, struct mbuf *, sa_family_t);
void if_rtrequest_dummy(struct ifnet *, int, struct rtentry *);
void p2p_rtrequest(struct ifnet *, int, struct rtentry *);
void p2p_input(struct ifnet *, struct mbuf *, struct netstack *);
int p2p_bpf_mtap(caddr_t, const struct mbuf *, u_int);
static inline void
if_input_process_proto(struct ifnet *ifp, struct mbuf *m, struct netstack *ns)
{
void (*input)(struct ifnet *, struct mbuf *, struct netstack *);
input = m->m_pkthdr.ph_cookie;
(*input)(ifp, m, ns);
}
struct ifaddr *ifa_ifwithaddr(const struct sockaddr *, u_int);
struct ifaddr *ifa_ifwithdstaddr(const struct sockaddr *, u_int);
struct ifaddr *ifaof_ifpforaddr(const struct sockaddr *, struct ifnet *);
struct ifaddr *ifaref(struct ifaddr *);
void ifafree(struct ifaddr *);
int if_isconnected(const struct ifnet *, unsigned int);
void if_clone_attach(struct if_clone *);
int if_clone_create(const char *, int);
int if_clone_destroy(const char *);
struct if_clone *
if_clone_lookup(const char *, int *);
void ifa_add(struct ifnet *, struct ifaddr *);
void ifa_del(struct ifnet *, struct ifaddr *);
void ifa_update_broadaddr(struct ifnet *, struct ifaddr *,
struct sockaddr *);
void if_addrhook_add(struct ifnet *, struct task *);
void if_addrhook_del(struct ifnet *, struct task *);
void if_addrhooks_run(struct ifnet *);
void if_linkstatehook_add(struct ifnet *, struct task *);
void if_linkstatehook_del(struct ifnet *, struct task *);
void if_detachhook_add(struct ifnet *, struct task *);
void if_detachhook_del(struct ifnet *, struct task *);
void if_rxr_livelocked(struct if_rxring *);
void if_rxr_init(struct if_rxring *, u_int, u_int);
u_int if_rxr_get(struct if_rxring *, u_int);
#define if_rxr_put(_r, _c) do { (_r)->rxr_alive -= (_c); } while (0)
#define if_rxr_needrefill(_r) ((_r)->rxr_alive < (_r)->rxr_lwm)
#define if_rxr_inuse(_r) ((_r)->rxr_alive)
#define if_rxr_cwm(_r) ((_r)->rxr_cwm)
int if_rxr_info_ioctl(struct if_rxrinfo *, u_int, struct if_rxring_info *);
int if_rxr_ioctl(struct if_rxrinfo *, const char *, u_int,
struct if_rxring *);
void if_counters_alloc(struct ifnet *);
void if_counters_free(struct ifnet *);
int if_txhprio_l2_check(int);
int if_txhprio_l3_check(int);
int if_rxhprio_l2_check(int);
int if_rxhprio_l3_check(int);
#endif
#endif