ifq.h revision 106931
11573Srgrimes/*
21573Srgrimes * Copyright (c) 1982, 1986, 1989, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 3. All advertising materials mentioning features or use of this software
141573Srgrimes *    must display the following acknowledgement:
151573Srgrimes *	This product includes software developed by the University of
161573Srgrimes *	California, Berkeley and its contributors.
171573Srgrimes * 4. Neither the name of the University nor the names of its contributors
181573Srgrimes *    may be used to endorse or promote products derived from this software
191573Srgrimes *    without specific prior written permission.
201573Srgrimes *
211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3189999Sobrien * SUCH DAMAGE.
321573Srgrimes *
3390045Sobrien *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3490030Sobrien * $FreeBSD: head/sys/net/if_var.h 106931 2002-11-14 23:36:28Z sam $
3589999Sobrien */
361573Srgrimes
37113984Snectar#ifndef	_NET_IF_VAR_H_
381573Srgrimes#define	_NET_IF_VAR_H_
391573Srgrimes
4065532Snectar/*
4165532Snectar * Structures defining a network interface, providing a packet
4265532Snectar * transport mechanism (ala level 0 of the PUP protocols).
4365532Snectar *
4465532Snectar * Each interface accepts output datagrams of a specified maximum
451573Srgrimes * length, and provides higher level routines with input datagrams
461573Srgrimes * received from its medium.
4765532Snectar *
4865532Snectar * Output occurs when the routine if_output is called, with three parameters:
491573Srgrimes *	(*ifp->if_output)(ifp, m, dst, rt)
501573Srgrimes * Here m is the mbuf chain to be sent and dst is the destination address.
5165532Snectar * The output routine encapsulates the supplied datagram if necessary,
5265532Snectar * and then transmits it on its medium.
5365532Snectar *
5465532Snectar * On input, each interface unwraps the data received by it, and either
5565532Snectar * places it on the input queue of a internetwork datagram routine
5665532Snectar * and posts the associated software interrupt, or passes the datagram to a raw
5765532Snectar * packet input routine.
5865532Snectar *
59113984Snectar * Routines exist for locating interfaces by their addresses
6065532Snectar * or for locating a interface on a certain network, as well as more general
611573Srgrimes * routing and gateway routines maintaining information used to locate
621573Srgrimes * interfaces.  These routines live in the files if.c and route.c
631573Srgrimes */
641573Srgrimes
651573Srgrimes#ifdef __STDC__
6665532Snectar/*
6765532Snectar * Forward structure declarations for function prototypes [sic].
6865532Snectar */
691573Srgrimesstruct	mbuf;
7090045Sobrienstruct	thread;
7165532Snectarstruct	rtentry;
721573Srgrimesstruct	rt_addrinfo;
7365532Snectarstruct	socket;
741573Srgrimesstruct	ether_header;
751573Srgrimes#endif
7665532Snectar
771573Srgrimes#include <sys/_label.h>		/* struct label */
781573Srgrimes#include <sys/queue.h>		/* get TAILQ macros */
791573Srgrimes
801573Srgrimes#ifdef _KERNEL
811573Srgrimes#include <sys/mbuf.h>
8265532Snectar#endif /* _KERNEL */
8365532Snectar#include <sys/lock.h>		/* XXX */
841573Srgrimes#include <sys/mutex.h>		/* XXX */
851573Srgrimes#include <sys/event.h>		/* XXX */
861573Srgrimes
871573SrgrimesTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
881573SrgrimesTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
891573SrgrimesTAILQ_HEAD(ifprefixhead, ifprefix);
9065532SnectarTAILQ_HEAD(ifmultihead, ifmultiaddr);
911573Srgrimes
92112407Srobert/*
9365532Snectar * Structure defining a queue for a network interface.
94112407Srobert */
95112407Srobertstruct	ifqueue {
961573Srgrimes	struct	mbuf *ifq_head;
971573Srgrimes	struct	mbuf *ifq_tail;
981573Srgrimes	int	ifq_len;
991573Srgrimes	int	ifq_maxlen;
10065532Snectar	int	ifq_drops;
1011573Srgrimes	struct	mtx ifq_mtx;
1021573Srgrimes};
1031573Srgrimes
1041573Srgrimes/*
1051573Srgrimes * Structure defining a network interface.
10665532Snectar *
10790045Sobrien * (Would like to call this struct ``if'', but C isn't PL/1.)
10865532Snectar */
10965532Snectar
11065532Snectar/*
11165532Snectar * NB: For FreeBSD, it is assumed that each NIC driver's softc starts with
11265532Snectar * one of these structures, typically held within an arpcom structure.
11365532Snectar *
11465532Snectar *	struct <foo>_softc {
1151573Srgrimes *		struct arpcom {
11665532Snectar *			struct  ifnet ac_if;
11765532Snectar *			...
11865532Snectar *		} <arpcom> ;
1191573Srgrimes *		...
12065532Snectar *	};
12165532Snectar *
12265532Snectar * The assumption is used in a number of places, including many
12365532Snectar * files in sys/net, device drivers, and sys/dev/mii.c:miibus_attach().
1241573Srgrimes *
12565532Snectar * Unfortunately devices' softc are opaque, so we depend on this layout
12665532Snectar * to locate the struct ifnet from the softc in the generic code.
127199784Swollman *
1281573Srgrimes */
1291573Srgrimesstruct ifnet {
1301573Srgrimes	void	*if_softc;		/* pointer to driver state */
1311573Srgrimes	char	*if_name;		/* name, e.g. ``en'' or ``lo'' */
1321573Srgrimes	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
13365532Snectar	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
13465532Snectar	struct	klist if_klist;		/* events attached to this if */
1351573Srgrimes	int	if_pcount;		/* number of promiscuous listeners */
1361573Srgrimes	struct	bpf_if *if_bpf;		/* packet filter structure */
13765532Snectar	u_short	if_index;		/* numeric abbreviation for this if  */
1381573Srgrimes	short	if_unit;		/* sub-unit for lower level driver */
1391573Srgrimes	short	if_timer;		/* time 'til if_watchdog called */
14065532Snectar	u_short	if_nvlans;		/* number of active vlans */
1411573Srgrimes	int	if_flags;		/* up/down, broadcast, etc. */
14265532Snectar	int	if_capabilities;	/* interface capabilities */
14365532Snectar	int	if_capenable;		/* enabled features */
14490045Sobrien	int	if_ipending;		/* interrupts pending */
14565532Snectar	void	*if_linkmib;		/* link-type-specific MIB data */
14665532Snectar	size_t	if_linkmiblen;		/* length of above data */
14765532Snectar	struct	if_data if_data;
14865532Snectar	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
14965532Snectar	int	if_amcount;		/* number of all-multicast requests */
15065532Snectar/* procedure handles */
15165532Snectar	int	(*if_output)		/* output routine (enqueue) */
15265532Snectar		(struct ifnet *, struct mbuf *, struct sockaddr *,
15365532Snectar		     struct rtentry *);
15465532Snectar	void	(*if_input)		/* input routine (from h/w driver) */
15565532Snectar		(struct ifnet *, struct mbuf *);
15665532Snectar	void	(*if_start)		/* initiate output routine */
15765532Snectar		(struct ifnet *);
15865532Snectar	int	(*if_done)		/* output complete routine */
15965532Snectar		(struct ifnet *);	/* (XXX not used; fake prototype) */
16065532Snectar	int	(*if_ioctl)		/* ioctl routine */
16165532Snectar		(struct ifnet *, u_long, caddr_t);
16265532Snectar	void	(*if_watchdog)		/* timer routine */
16365532Snectar		(struct ifnet *);
16465532Snectar	int	(*if_poll_recv)		/* polled receive routine */
16565532Snectar		(struct ifnet *, int *);
16665532Snectar	int	(*if_poll_xmit)		/* polled transmit routine */
16765532Snectar		(struct ifnet *, int *);
16865532Snectar	void	(*if_poll_intren)	/* polled interrupt reenable routine */
16965532Snectar		(struct ifnet *);
17065532Snectar	void	(*if_poll_slowinput)	/* input routine for slow devices */
17165532Snectar		(struct ifnet *, struct mbuf *);
17265532Snectar	void	(*if_init)		/* Init routine */
17365532Snectar		(void *);
17465532Snectar	int	(*if_resolvemulti)	/* validate/resolve multicast */
17565532Snectar		(struct ifnet *, struct sockaddr **, struct sockaddr *);
17665532Snectar	struct	ifqueue if_snd;		/* output queue */
17765532Snectar	struct	ifqueue *if_poll_slowq;	/* input queue for slow devices */
17865532Snectar	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
17965532Snectar	u_int8_t *if_broadcastaddr;	/* linklevel broadcast bytestring */
18065532Snectar	struct	label if_label;		/* interface MAC label */
18165532Snectar};
18265532Snectar
18365532Snectartypedef void if_init_f_t(void *);
18465532Snectar
18565532Snectar#define	if_mtu		if_data.ifi_mtu
18665532Snectar#define	if_type		if_data.ifi_type
18765532Snectar#define if_physical	if_data.ifi_physical
18890045Sobrien#define	if_addrlen	if_data.ifi_addrlen
18965532Snectar#define	if_hdrlen	if_data.ifi_hdrlen
19065532Snectar#define	if_metric	if_data.ifi_metric
19165532Snectar#define	if_baudrate	if_data.ifi_baudrate
19265532Snectar#define	if_hwassist	if_data.ifi_hwassist
19365532Snectar#define	if_ipackets	if_data.ifi_ipackets
19465532Snectar#define	if_ierrors	if_data.ifi_ierrors
19565532Snectar#define	if_opackets	if_data.ifi_opackets
19665532Snectar#define	if_oerrors	if_data.ifi_oerrors
19765532Snectar#define	if_collisions	if_data.ifi_collisions
198112407Srobert#define	if_ibytes	if_data.ifi_ibytes
199112407Srobert#define	if_obytes	if_data.ifi_obytes
200112407Srobert#define	if_imcasts	if_data.ifi_imcasts
201112407Srobert#define	if_omcasts	if_data.ifi_omcasts
20265532Snectar#define	if_iqdrops	if_data.ifi_iqdrops
20365532Snectar#define	if_noproto	if_data.ifi_noproto
20465532Snectar#define	if_lastchange	if_data.ifi_lastchange
20565532Snectar#define if_recvquota	if_data.ifi_recvquota
20665532Snectar#define	if_xmitquota	if_data.ifi_xmitquota
20765532Snectar#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0)
20865532Snectar
20965532Snectar/* for compatibility with other BSDs */
21065532Snectar#define	if_addrlist	if_addrhead
21165532Snectar#define	if_list		if_link
21265532Snectar
21365532Snectar/*
21465532Snectar * Bit values in if_ipending
21565532Snectar */
21665532Snectar#define	IFI_RECV	1	/* I want to receive */
21765532Snectar#define	IFI_XMIT	2	/* I want to transmit */
218112407Srobert
219112407Srobert/*
220112407Srobert * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
221112407Srobert * are queues of messages stored on ifqueue structures
222112407Srobert * (defined above).  Entries are added to and deleted from these structures
223112407Srobert * by these macros, which should be called with ipl raised to splimp().
224112407Srobert */
225112407Srobert#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
226112407Srobert#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
22765532Snectar#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
22865532Snectar#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
229112407Srobert#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
230112407Srobert
231112407Srobert#define	_IF_ENQUEUE(ifq, m) do { 				\
232112407Srobert	(m)->m_nextpkt = NULL;					\
233112407Srobert	if ((ifq)->ifq_tail == NULL) 				\
234112407Srobert		(ifq)->ifq_head = m; 				\
235112407Srobert	else 							\
236112407Srobert		(ifq)->ifq_tail->m_nextpkt = m; 		\
237112407Srobert	(ifq)->ifq_tail = m; 					\
238112407Srobert	(ifq)->ifq_len++; 					\
239112407Srobert} while (0)
240112407Srobert
24165532Snectar#define IF_ENQUEUE(ifq, m) do {					\
242112407Srobert	IF_LOCK(ifq); 						\
243112407Srobert	_IF_ENQUEUE(ifq, m); 					\
24465532Snectar	IF_UNLOCK(ifq); 					\
24565532Snectar} while (0)
24665532Snectar
24765532Snectar#define	_IF_PREPEND(ifq, m) do {				\
24865532Snectar	(m)->m_nextpkt = (ifq)->ifq_head; 			\
24965532Snectar	if ((ifq)->ifq_tail == NULL) 				\
25065532Snectar		(ifq)->ifq_tail = (m); 				\
25165532Snectar	(ifq)->ifq_head = (m); 					\
25265532Snectar	(ifq)->ifq_len++; 					\
25365532Snectar} while (0)
25465532Snectar
25565532Snectar#define IF_PREPEND(ifq, m) do {		 			\
25665532Snectar	IF_LOCK(ifq); 						\
25765532Snectar	_IF_PREPEND(ifq, m); 					\
25865532Snectar	IF_UNLOCK(ifq); 					\
25965532Snectar} while (0)
260113984Snectar
26165532Snectar#define	_IF_DEQUEUE(ifq, m) do { 				\
26265532Snectar	(m) = (ifq)->ifq_head; 					\
26365532Snectar	if (m) { 						\
26465532Snectar		if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) 	\
26565532Snectar			(ifq)->ifq_tail = NULL; 		\
26665532Snectar		(m)->m_nextpkt = NULL; 				\
26765532Snectar		(ifq)->ifq_len--; 				\
26865532Snectar	} 							\
26965532Snectar} while (0)
27065532Snectar
271#define IF_DEQUEUE(ifq, m) do { 				\
272	IF_LOCK(ifq); 						\
273	_IF_DEQUEUE(ifq, m); 					\
274	IF_UNLOCK(ifq); 					\
275} while (0)
276
277#define IF_DRAIN(ifq) do { 					\
278	struct mbuf *m; 					\
279	IF_LOCK(ifq); 						\
280	for (;;) { 						\
281		_IF_DEQUEUE(ifq, m); 				\
282		if (m == NULL) 					\
283			break; 					\
284		m_freem(m); 					\
285	} 							\
286	IF_UNLOCK(ifq); 					\
287} while (0)
288
289#ifdef _KERNEL
290#define	IF_HANDOFF(ifq, m, ifp)			if_handoff(ifq, m, ifp, 0)
291#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	if_handoff(ifq, m, ifp, adj)
292
293static __inline int
294if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
295{
296	int active = 0;
297
298	IF_LOCK(ifq);
299	if (_IF_QFULL(ifq)) {
300		_IF_DROP(ifq);
301		IF_UNLOCK(ifq);
302		m_freem(m);
303		return (0);
304	}
305	if (ifp != NULL) {
306		ifp->if_obytes += m->m_pkthdr.len + adjust;
307		if (m->m_flags & M_MCAST)
308			ifp->if_omcasts++;
309		active = ifp->if_flags & IFF_OACTIVE;
310	}
311	_IF_ENQUEUE(ifq, m);
312	IF_UNLOCK(ifq);
313	if (ifp != NULL && !active)
314		(*ifp->if_start)(ifp);
315	return (1);
316}
317
318/*
319 * 72 was chosen below because it is the size of a TCP/IP
320 * header (40) + the minimum mss (32).
321 */
322#define	IF_MINMTU	72
323#define	IF_MAXMTU	65535
324
325#endif /* _KERNEL */
326
327/*
328 * The ifaddr structure contains information about one address
329 * of an interface.  They are maintained by the different address families,
330 * are allocated and attached when an address is set, and are linked
331 * together so all addresses for an interface can be located.
332 */
333struct ifaddr {
334	struct	sockaddr *ifa_addr;	/* address of interface */
335	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
336#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
337	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
338	struct	if_data if_data;	/* not all members are meaningful */
339	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
340	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
341	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
342		(int, struct rtentry *, struct rt_addrinfo *);
343	u_short	ifa_flags;		/* mostly rt_flags for cloning */
344	u_int	ifa_refcnt;		/* references to this structure */
345	int	ifa_metric;		/* cost of going out this interface */
346#ifdef notdef
347	struct	rtentry *ifa_rt;	/* XXXX for ROUTETOIF ????? */
348#endif
349	int (*ifa_claim_addr)		/* check if an addr goes to this if */
350		(struct ifaddr *, struct sockaddr *);
351
352};
353#define	IFA_ROUTE	RTF_UP		/* route installed */
354
355/* for compatibility with other BSDs */
356#define	ifa_list	ifa_link
357
358/*
359 * The prefix structure contains information about one prefix
360 * of an interface.  They are maintained by the different address families,
361 * are allocated and attached when an prefix or an address is set,
362 * and are linked together so all prefixes for an interface can be located.
363 */
364struct ifprefix {
365	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
366	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
367	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
368	u_char	ifpr_plen;		/* prefix length in bits */
369	u_char	ifpr_type;		/* protocol dependent prefix type */
370};
371
372/*
373 * Multicast address structure.  This is analogous to the ifaddr
374 * structure except that it keeps track of multicast addresses.
375 * Also, the reference count here is a count of requests for this
376 * address, not a count of pointers to this structure.
377 */
378struct ifmultiaddr {
379	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
380	struct	sockaddr *ifma_addr; 	/* address this membership is for */
381	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
382	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
383	u_int	ifma_refcount;		/* reference count */
384	void	*ifma_protospec;	/* protocol-specific state, if any */
385};
386
387#ifdef _KERNEL
388#define	IFAFREE(ifa) \
389	do { \
390		if ((ifa)->ifa_refcnt <= 0) \
391			ifafree(ifa); \
392		else \
393			(ifa)->ifa_refcnt--; \
394	} while (0)
395
396struct ifindex_entry {
397	struct	ifnet *ife_ifnet;
398	struct	ifaddr *ife_ifnet_addr;
399	dev_t	ife_dev;
400};
401
402#define ifnet_byindex(idx)	ifindex_table[(idx)].ife_ifnet
403#define ifaddr_byindex(idx)	ifindex_table[(idx)].ife_ifnet_addr
404#define ifdev_byindex(idx)	ifindex_table[(idx)].ife_dev
405
406extern	struct ifnethead ifnet;
407extern	struct ifindex_entry *ifindex_table;
408extern	int ifqmaxlen;
409extern	struct ifnet *loif;	/* first loopback interface */
410extern	int if_index;
411
412int	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
413int	if_allmulti(struct ifnet *, int);
414void	if_attach(struct ifnet *);
415int	if_delmulti(struct ifnet *, struct sockaddr *);
416void	if_detach(struct ifnet *);
417void	if_down(struct ifnet *);
418int	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
419void	if_route(struct ifnet *, int flag, int fam);
420int	if_setlladdr(struct ifnet *, const u_char *, int);
421void	if_unroute(struct ifnet *, int flag, int fam);
422void	if_up(struct ifnet *);
423/*void	ifinit(void);*/ /* declared in systm.h for main() */
424int	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
425int	ifpromisc(struct ifnet *, int);
426struct	ifnet *ifunit(const char *);
427struct	ifnet *if_withname(struct sockaddr *);
428
429int	if_poll_recv_slow(struct ifnet *ifp, int *quotap);
430void	if_poll_xmit_slow(struct ifnet *ifp, int *quotap);
431void	if_poll_throttle(void);
432void	if_poll_unthrottle(void *);
433void	if_poll_init(void);
434void	if_poll(void);
435
436struct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
437struct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
438struct	ifaddr *ifa_ifwithnet(struct sockaddr *);
439struct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
440struct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
441void	ifafree(struct ifaddr *);
442
443struct	ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *);
444int	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
445
446void	if_clone_attach(struct if_clone *);
447void	if_clone_detach(struct if_clone *);
448
449int	if_clone_create(char *, int);
450int	if_clone_destroy(const char *);
451
452#define IF_LLADDR(ifp)							\
453    LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr)
454
455#ifdef DEVICE_POLLING
456enum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS, POLL_DEREGISTER };
457
458typedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
459int    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
460int    ether_poll_deregister(struct ifnet *ifp);
461#endif /* DEVICE_POLLING */
462
463#endif /* _KERNEL */
464
465#endif /* !_NET_IF_VAR_H_ */
466