code:
/*	$NetBSD: ieee8023ad_impl.h,v 1.2 2005/12/10 23:21:39 elad Exp $	*/

/*-
 * Copyright (c)2005 YAMAMOTO Takashi,
 * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
 *
 * $FreeBSD: release/9.0.0/sys/net/ieee8023ad_lacp.h 177289 2008-03-17 01:26:44Z thompsa $
 */

/*
 * IEEE802.3ad LACP
 *
 * implementation details.
 */

#define	LACP_TIMER_CURRENT_WHILE	0
#define	LACP_TIMER_PERIODIC		1
#define	LACP_TIMER_WAIT_WHILE		2
#define	LACP_NTIMER			3

#define	LACP_TIMER_ARM(port, timer, val) \
	(port)->lp_timer[(timer)] = (val)
#define	LACP_TIMER_DISARM(port, timer) \
	(port)->lp_timer[(timer)] = 0
#define	LACP_TIMER_ISARMED(port, timer) \
	((port)->lp_timer[(timer)] > 0)

/*
 * IEEE802.3ad LACP
 *
 * protocol definitions.
 */

#define	LACP_STATE_ACTIVITY	(1<<0)
#define	LACP_STATE_TIMEOUT	(1<<1)
#define	LACP_STATE_AGGREGATION	(1<<2)
#define	LACP_STATE_SYNC		(1<<3)
#define	LACP_STATE_COLLECTING	(1<<4)
#define	LACP_STATE_DISTRIBUTING	(1<<5)
#define	LACP_STATE_DEFAULTED	(1<<6)
#define	LACP_STATE_EXPIRED	(1<<7)

#define	LACP_PORT_NTT		0x00000001
#define	LACP_PORT_MARK		0x00000002

#define	LACP_STATE_BITS		\
	"\020"			\
	"\001ACTIVITY"		\
	"\002TIMEOUT"		\
	"\003AGGREGATION"	\
	"\004SYNC"		\
	"\005COLLECTING"	\
	"\006DISTRIBUTING"	\
	"\007DEFAULTED"		\
	"\010EXPIRED"

/*
 * IEEE802.3 slow protocols
 *
 * protocol (on-wire) definitions.
 *
 * XXX should be elsewhere.
 */

#define	SLOWPROTOCOLS_SUBTYPE_LACP	1
#define	SLOWPROTOCOLS_SUBTYPE_MARKER	2

struct slowprothdr {
	uint8_t		sph_subtype;
	uint8_t		sph_version;
} __packed;

/*
 * TLV on-wire structure.
 */

struct tlvhdr {
	uint8_t		tlv_type;
	uint8_t		tlv_length;
	/* uint8_t tlv_value[]; */
} __packed;

/*
 * ... and our implementation.
 */

#define	TLV_SET(tlv, type, length) \
	do { \
		(tlv)->tlv_type = (type); \
		(tlv)->tlv_length = sizeof(*tlv) + (length); \
	} while (/*CONSTCOND*/0)

struct tlv_template {
	uint8_t			tmpl_type;
	uint8_t			tmpl_length;
};

struct lacp_systemid {
	uint16_t		lsi_prio;
	uint8_t			lsi_mac[6];
} __packed;

struct lacp_portid {
	uint16_t		lpi_prio;
	uint16_t		lpi_portno;
} __packed;

struct lacp_peerinfo {
	struct lacp_systemid	lip_systemid;
	uint16_t		lip_key;
	struct lacp_portid	lip_portid;
	uint8_t			lip_state;
	uint8_t			lip_resv[3];
} __packed;

struct lacp_collectorinfo {
	uint16_t		lci_maxdelay;
	uint8_t			lci_resv[12];
} __packed;

struct lacpdu {
	struct ether_header	ldu_eh;
	struct slowprothdr	ldu_sph;

	struct tlvhdr		ldu_tlv_actor;
	struct lacp_peerinfo	ldu_actor;
	struct tlvhdr		ldu_tlv_partner;
	struct lacp_peerinfo	ldu_partner;
	struct tlvhdr		ldu_tlv_collector;
	struct lacp_collectorinfo ldu_collector;
	struct tlvhdr		ldu_tlv_term;
	uint8_t			ldu_resv[50];
} __packed;

/*
 * IEEE802.3ad marker protocol
 *
 * protocol (on-wire) definitions.
 */
struct lacp_markerinfo {
	uint16_t		mi_rq_port;
	uint8_t			mi_rq_system[ETHER_ADDR_LEN];
	uint32_t		mi_rq_xid;
	uint8_t			mi_pad[2];
} __packed;

struct markerdu {
	struct ether_header	mdu_eh;
	struct slowprothdr	mdu_sph;

	struct tlvhdr		mdu_tlv;
	struct lacp_markerinfo	mdu_info;
	struct tlvhdr		mdu_tlv_term;
	uint8_t			mdu_resv[90];
} __packed;

#define	MARKER_TYPE_INFO	0x01
#define	MARKER_TYPE_RESPONSE	0x02

enum lacp_selected {
	LACP_UNSELECTED,
	LACP_STANDBY,	/* not used in this implementation */
	LACP_SELECTED,
};

enum lacp_mux_state {
	LACP_MUX_DETACHED,
	LACP_MUX_WAITING,
	LACP_MUX_ATTACHED,
	LACP_MUX_COLLECTING,
	LACP_MUX_DISTRIBUTING,
};

#define	LACP_MAX_PORTS		32

struct lacp_portmap {
	int			pm_count;
	struct lacp_port	*pm_map[LACP_MAX_PORTS];
};

struct lacp_port {
	TAILQ_ENTRY(lacp_port)	lp_dist_q;
	LIST_ENTRY(lacp_port)	lp_next;
	struct lacp_softc	*lp_lsc;
	struct lagg_port	*lp_lagg;
	struct ifnet		*lp_ifp;
	struct lacp_peerinfo	lp_partner;
	struct lacp_peerinfo	lp_actor;
	struct lacp_markerinfo	lp_marker;
#define	lp_state	lp_actor.lip_state
#define	lp_key		lp_actor.lip_key
#define	lp_systemid	lp_actor.lip_systemid
	struct timeval		lp_last_lacpdu;
	int			lp_lacpdu_sent;
	enum lacp_mux_state	lp_mux_state;
	enum lacp_selected	lp_selected;
	int			lp_flags;
	u_int			lp_media; /* XXX redundant */
	int			lp_timer[LACP_NTIMER];
	struct ifmultiaddr	*lp_ifma;

	struct lacp_aggregator	*lp_aggregator;
};

struct lacp_aggregator {
	TAILQ_ENTRY(lacp_aggregator)	la_q;
	int			la_refcnt; /* num of ports which selected us */
	int			la_nports; /* num of distributing ports  */
	TAILQ_HEAD(, lacp_port)	la_ports; /* distributing ports */
	struct lacp_peerinfo	la_partner;
	struct lacp_peerinfo	la_actor;
	int			la_pending; /* number of ports in wait_while */
};

struct lacp_softc {
	struct lagg_softc	*lsc_softc;
	struct mtx		lsc_mtx;
	struct lacp_aggregator	*lsc_active_aggregator;
	TAILQ_HEAD(, lacp_aggregator) lsc_aggregators;
	boolean_t		lsc_suppress_distributing;
	struct callout		lsc_transit_callout;
	struct callout		lsc_callout;
	LIST_HEAD(, lacp_port)	lsc_ports;
	struct lacp_portmap	lsc_pmap[2];
	volatile u_int		lsc_activemap;
	u_int32_t		lsc_hashkey;
};

#define	LACP_TYPE_ACTORINFO	1
#define	LACP_TYPE_PARTNERINFO	2
#define	LACP_TYPE_COLLECTORINFO	3

/* timeout values (in sec) */
#define	LACP_FAST_PERIODIC_TIME		(1)
#define	LACP_SLOW_PERIODIC_TIME		(30)
#define	LACP_SHORT_TIMEOUT_TIME		(3 * LACP_FAST_PERIODIC_TIME)
#define	LACP_LONG_TIMEOUT_TIME		(3 * LACP_SLOW_PERIODIC_TIME)
#define	LACP_CHURN_DETECTION_TIME	(60)
#define	LACP_AGGREGATE_WAIT_TIME	(2)
#define	LACP_TRANSIT_DELAY		3000	/* in msec */

#define	LACP_STATE_EQ(s1, s2, mask)	\
	((((s1) ^ (s2)) & (mask)) == 0)

#define	LACP_SYS_PRI(peer)	(peer).lip_systemid.lsi_prio

#define	LACP_PORT(_lp)	((struct lacp_port *)(_lp)->lp_psc)
#define	LACP_SOFTC(_sc)	((struct lacp_softc *)(_sc)->sc_psc)

#define LACP_LOCK_INIT(_lsc)		mtx_init(&(_lsc)->lsc_mtx, \
					    "lacp mtx", NULL, MTX_DEF)
#define LACP_LOCK_DESTROY(_lsc)		mtx_destroy(&(_lsc)->lsc_mtx)
#define LACP_LOCK(_lsc)			mtx_lock(&(_lsc)->lsc_mtx)
#define LACP_UNLOCK(_lsc)		mtx_unlock(&(_lsc)->lsc_mtx)
#define LACP_LOCK_ASSERT(_lsc)		mtx_assert(&(_lsc)->lsc_mtx, MA_OWNED)

struct mbuf	*lacp_input(struct lagg_port *, struct mbuf *);
struct lagg_port *lacp_select_tx_port(struct lagg_softc *, struct mbuf *);
int		lacp_attach(struct lagg_softc *);
int		lacp_detach(struct lagg_softc *);
void		lacp_init(struct lagg_softc *);
void		lacp_stop(struct lagg_softc *);
int		lacp_port_create(struct lagg_port *);
void		lacp_port_destroy(struct lagg_port *);
void		lacp_linkstate(struct lagg_port *);
void		lacp_req(struct lagg_softc *, caddr_t);
void		lacp_portreq(struct lagg_port *, caddr_t);

static __inline int
lacp_isactive(struct lagg_port *lgp)
{
	struct lacp_port *lp = LACP_PORT(lgp);
	struct lacp_softc *lsc = lp->lp_lsc;
	struct lacp_aggregator *la = lp->lp_aggregator;

	/* This port is joined to the active aggregator */
	if (la != NULL && la == lsc->lsc_active_aggregator)
		return (1);

	return (0);
}

static __inline int
lacp_iscollecting(struct lagg_port *lgp)
{
	struct lacp_port *lp = LACP_PORT(lgp);

	return ((lp->lp_state & LACP_STATE_COLLECTING) != 0);
}

static __inline int
lacp_isdistributing(struct lagg_port *lgp)
{
	struct lacp_port *lp = LACP_PORT(lgp);

	return ((lp->lp_state & LACP_STATE_DISTRIBUTING) != 0);
}

/* following constants don't include terminating NUL */
#define	LACP_MACSTR_MAX		(2*6 + 5)
#define	LACP_SYSTEMPRIOSTR_MAX	(4)
#define	LACP_SYSTEMIDSTR_MAX	(LACP_SYSTEMPRIOSTR_MAX + 1 + LACP_MACSTR_MAX)
#define	LACP_PORTPRIOSTR_MAX	(4)
#define	LACP_PORTNOSTR_MAX	(4)
#define	LACP_PORTIDSTR_MAX	(LACP_PORTPRIOSTR_MAX + 1 + LACP_PORTNOSTR_MAX)
#define	LACP_KEYSTR_MAX		(4)
#define	LACP_PARTNERSTR_MAX	\
	(1 + LACP_SYSTEMIDSTR_MAX + 1 + LACP_KEYSTR_MAX + 1 \
	+ LACP_PORTIDSTR_MAX + 1)
#define	LACP_LAGIDSTR_MAX	\
	(1 + LACP_PARTNERSTR_MAX + 1 + LACP_PARTNERSTR_MAX + 1)
#define	LACP_STATESTR_MAX	(255) /* XXX */


code:
/*-
 * Copyright (c) 1982, 1986, 1989, 1993
 *	The Regents of the University of California.  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.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
 *
 *	@(#)if.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: release/9.0.0/sys/net/if.h 223735 2011-07-03 12:22:02Z bz $
 */

#ifndef _NET_IF_H_
#define	_NET_IF_H_

#include <sys/cdefs.h>

#ifdef _KERNEL
#include <sys/queue.h>
#endif

#if __BSD_VISIBLE
/*
 * <net/if.h> does not depend on <sys/time.h> on most other systems.  This
 * helps userland compatibility.  (struct timeval ifi_lastchange)
 */
#ifndef _KERNEL
#include <sys/time.h>
#endif

struct ifnet;
#endif

/*
 * Length of interface external name, including terminating '\0'.
 * Note: this is the same size as a generic device's external name.
 */
#define		IF_NAMESIZE	16
#if __BSD_VISIBLE
#define		IFNAMSIZ	IF_NAMESIZE
#define		IF_MAXUNIT	0x7fff	/* historical value */
#endif
#if __BSD_VISIBLE

/*
 * Structure used to query names of interface cloners.
 */

struct if_clonereq {
	int	ifcr_total;		/* total cloners (out) */
	int	ifcr_count;		/* room for this many in user buffer */
	char	*ifcr_buffer;		/* buffer for cloner names */
};

/*
 * Structure describing information about an interface
 * which may be of interest to management entities.
 */
struct if_data {
	/* generic interface information */
	u_char	ifi_type;		/* ethernet, tokenring, etc */
	u_char	ifi_physical;		/* e.g., AUI, Thinnet, 10base-T, etc */
	u_char	ifi_addrlen;		/* media address length */
	u_char	ifi_hdrlen;		/* media header length */
	u_char	ifi_link_state;		/* current link state */
	u_char	ifi_spare_char1;	/* spare byte */
	u_char	ifi_spare_char2;	/* spare byte */
	u_char	ifi_datalen;		/* length of this data struct */
	u_long	ifi_mtu;		/* maximum transmission unit */
	u_long	ifi_metric;		/* routing metric (external only) */
	u_long	ifi_baudrate;		/* linespeed */
	/* volatile statistics */
	u_long	ifi_ipackets;		/* packets received on interface */
	u_long	ifi_ierrors;		/* input errors on interface */
	u_long	ifi_opackets;		/* packets sent on interface */
	u_long	ifi_oerrors;		/* output errors on interface */
	u_long	ifi_collisions;		/* collisions on csma interfaces */
	u_long	ifi_ibytes;		/* total number of octets received */
	u_long	ifi_obytes;		/* total number of octets sent */
	u_long	ifi_imcasts;		/* packets received via multicast */
	u_long	ifi_omcasts;		/* packets sent via multicast */
	u_long	ifi_iqdrops;		/* dropped on input, this interface */
	u_long	ifi_noproto;		/* destined for unsupported protocol */
	u_long	ifi_hwassist;		/* HW offload capabilities, see IFCAP */
	time_t	ifi_epoch;		/* uptime at attach or stat reset */
	struct	timeval ifi_lastchange;	/* time of last administrative change */
};

/*-
 * Interface flags are of two types: network stack owned flags, and driver
 * owned flags.  Historically, these values were stored in the same ifnet
 * flags field, but with the advent of fine-grained locking, they have been
 * broken out such that the network stack is responsible for synchronizing
 * the stack-owned fields, and the device driver the device-owned fields.
 * Both halves can perform lockless reads of the other half's field, subject
 * to accepting the involved races.
 *
 * Both sets of flags come from the same number space, and should not be
 * permitted to conflict, as they are exposed to user space via a single
 * field.
 *
 * The following symbols identify read and write requirements for fields:
 *
 * (i) if_flags field set by device driver before attach, read-only there
 *     after.
 * (n) if_flags field written only by the network stack, read by either the
 *     stack or driver.
 * (d) if_drv_flags field written only by the device driver, read by either
 *     the stack or driver.
 */
#define	IFF_UP		0x1		/* (n) interface is up */
#define	IFF_BROADCAST	0x2		/* (i) broadcast address valid */
#define	IFF_DEBUG	0x4		/* (n) turn on debugging */
#define	IFF_LOOPBACK	0x8		/* (i) is a loopback net */
#define	IFF_POINTOPOINT	0x10		/* (i) is a point-to-point link */
#define	IFF_SMART	0x20		/* (i) interface manages own routes */
#define	IFF_DRV_RUNNING	0x40		/* (d) resources allocated */
#define	IFF_NOARP	0x80		/* (n) no address resolution protocol */
#define	IFF_PROMISC	0x100		/* (n) receive all packets */
#define	IFF_ALLMULTI	0x200		/* (n) receive all multicast packets */
#define	IFF_DRV_OACTIVE	0x400		/* (d) tx hardware queue is full */
#define	IFF_SIMPLEX	0x800		/* (i) can't hear own transmissions */
#define	IFF_LINK0	0x1000		/* per link layer defined bit */
#define	IFF_LINK1	0x2000		/* per link layer defined bit */
#define	IFF_LINK2	0x4000		/* per link layer defined bit */
#define	IFF_ALTPHYS	IFF_LINK2	/* use alternate physical connection */
#define	IFF_MULTICAST	0x8000		/* (i) supports multicast */
#define	IFF_CANTCONFIG	0x10000		/* (i) unconfigurable using ioctl(2) */
#define	IFF_PPROMISC	0x20000		/* (n) user-requested promisc mode */
#define	IFF_MONITOR	0x40000		/* (n) user-requested monitor mode */
#define	IFF_STATICARP	0x80000		/* (n) static ARP */
#define	IFF_DYING	0x200000	/* (n) interface is winding down */
#define	IFF_RENAMING	0x400000	/* (n) interface is being renamed */

/*
 * Old names for driver flags so that user space tools can continue to use
 * the old (portable) names.
 */
#ifndef _KERNEL
#define	IFF_RUNNING	IFF_DRV_RUNNING
#define	IFF_OACTIVE	IFF_DRV_OACTIVE
#endif

/* flags set internally only: */
#define	IFF_CANTCHANGE \
	(IFF_BROADCAST|IFF_POINTOPOINT|IFF_DRV_RUNNING|IFF_DRV_OACTIVE|\
	    IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART|IFF_PROMISC|\
	    IFF_DYING|IFF_CANTCONFIG)

/*
 * Values for if_link_state.
 */
#define	LINK_STATE_UNKNOWN	0	/* link invalid/unknown */
#define	LINK_STATE_DOWN		1	/* link is down */
#define	LINK_STATE_UP		2	/* link is up */

/*
 * Some convenience macros used for setting ifi_baudrate.
 * XXX 1000 vs. 1024? --thorpej@netbsd.org
 */
#define	IF_Kbps(x)	((x) * 1000)		/* kilobits/sec. */
#define	IF_Mbps(x)	(IF_Kbps((x) * 1000))	/* megabits/sec. */
#define	IF_Gbps(x)	(IF_Mbps((x) * 1000))	/* gigabits/sec. */

/*
 * Capabilities that interfaces can advertise.
 *
 * struct ifnet.if_capabilities
 *   contains the optional features & capabilities a particular interface
 *   supports (not only the driver but also the detected hw revision).
 *   Capabilities are defined by IFCAP_* below.
 * struct ifnet.if_capenable
 *   contains the enabled (either by default or through ifconfig) optional
 *   features & capabilities on this interface.
 *   Capabilities are defined by IFCAP_* below.
 * struct if_data.ifi_hwassist in mbuf CSUM_ flag form, controlled by above
 *   contains the enabled optional feature & capabilites that can be used
 *   individually per packet and are specified in the mbuf pkthdr.csum_flags
 *   field.  IFCAP_* and CSUM_* do not match one to one and CSUM_* may be
 *   more detailed or differenciated than IFCAP_*.
 *   Hwassist features are defined CSUM_* in sys/mbuf.h
 *
 * Capabilities that cannot be arbitrarily changed with ifconfig/ioctl
 * are listed in IFCAP_CANTCHANGE, similar to IFF_CANTCHANGE.
 * This is not strictly necessary because the common code never
 * changes capabilities, and it is left to the individual driver
 * to do the right thing. However, having the filter here
 * avoids replication of the same code in all individual drivers.
 */
#define	IFCAP_RXCSUM		0x00001  /* can offload checksum on RX */
#define	IFCAP_TXCSUM		0x00002  /* can offload checksum on TX */
#define	IFCAP_NETCONS		0x00004  /* can be a network console */
#define	IFCAP_VLAN_MTU		0x00008	/* VLAN-compatible MTU */
#define	IFCAP_VLAN_HWTAGGING	0x00010	/* hardware VLAN tag support */
#define	IFCAP_JUMBO_MTU		0x00020	/* 9000 byte MTU supported */
#define	IFCAP_POLLING		0x00040	/* driver supports polling */
#define	IFCAP_VLAN_HWCSUM	0x00080	/* can do IFCAP_HWCSUM on VLANs */
#define	IFCAP_TSO4		0x00100	/* can do TCP Segmentation Offload */
#define	IFCAP_TSO6		0x00200	/* can do TCP6 Segmentation Offload */
#define	IFCAP_LRO		0x00400	/* can do Large Receive Offload */
#define	IFCAP_WOL_UCAST		0x00800	/* wake on any unicast frame */
#define	IFCAP_WOL_MCAST		0x01000	/* wake on any multicast frame */
#define	IFCAP_WOL_MAGIC		0x02000	/* wake on any Magic Packet */
#define	IFCAP_TOE4		0x04000	/* interface can offload TCP */
#define	IFCAP_TOE6		0x08000	/* interface can offload TCP6 */
#define	IFCAP_VLAN_HWFILTER	0x10000 /* interface hw can filter vlan tag */
#define	IFCAP_POLLING_NOCOUNT	0x20000 /* polling ticks cannot be fragmented */
#define	IFCAP_VLAN_HWTSO	0x40000 /* can do IFCAP_TSO on VLANs */
#define	IFCAP_LINKSTATE		0x80000 /* the runtime link state is dynamic */
#define	IFCAP_NETMAP		0x100000 /* netmap mode supported/enabled */

#define IFCAP_HWCSUM	(IFCAP_RXCSUM | IFCAP_TXCSUM)
#define	IFCAP_TSO	(IFCAP_TSO4 | IFCAP_TSO6)
#define	IFCAP_WOL	(IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC)
#define	IFCAP_TOE	(IFCAP_TOE4 | IFCAP_TOE6)

#define	IFCAP_CANTCHANGE	(IFCAP_NETMAP)

#define	IFQ_MAXLEN	50
#define	IFNET_SLOWHZ	1		/* granularity is 1 second */

/*
 * Message format for use in obtaining information about interfaces
 * from getkerninfo and the routing socket
 */
struct if_msghdr {
	u_short	ifm_msglen;	/* to skip over non-understood messages */
	u_char	ifm_version;	/* future binary compatibility */
	u_char	ifm_type;	/* message type */
	int	ifm_addrs;	/* like rtm_addrs */
	int	ifm_flags;	/* value of if_flags */
	u_short	ifm_index;	/* index for associated ifp */
	struct	if_data ifm_data;/* statistics and other data about if */
};

/*
 * Message format for use in obtaining information about interface addresses
 * from getkerninfo and the routing socket
 */
struct ifa_msghdr {
	u_short	ifam_msglen;	/* to skip over non-understood messages */
	u_char	ifam_version;	/* future binary compatibility */
	u_char	ifam_type;	/* message type */
	int	ifam_addrs;	/* like rtm_addrs */
	int	ifam_flags;	/* value of ifa_flags */
	u_short	ifam_index;	/* index for associated ifp */
	int	ifam_metric;	/* value of ifa_metric */
};

/*
 * Message format for use in obtaining information about multicast addresses
 * from the routing socket
 */
struct ifma_msghdr {
	u_short	ifmam_msglen;	/* to skip over non-understood messages */
	u_char	ifmam_version;	/* future binary compatibility */
	u_char	ifmam_type;	/* message type */
	int	ifmam_addrs;	/* like rtm_addrs */
	int	ifmam_flags;	/* value of ifa_flags */
	u_short	ifmam_index;	/* index for associated ifp */
};

/*
 * Message format announcing the arrival or departure of a network interface.
 */
struct if_announcemsghdr {
	u_short	ifan_msglen;	/* to skip over non-understood messages */
	u_char	ifan_version;	/* future binary compatibility */
	u_char	ifan_type;	/* message type */
	u_short	ifan_index;	/* index for associated ifp */
	char	ifan_name[IFNAMSIZ]; /* if name, e.g. "en0" */
	u_short	ifan_what;	/* what type of announcement */
};

#define	IFAN_ARRIVAL	0	/* interface arrival */
#define	IFAN_DEPARTURE	1	/* interface departure */

/*
 * Buffer with length to be used in SIOCGIFDESCR/SIOCSIFDESCR requests
 */
struct ifreq_buffer {
	size_t	length;
	void	*buffer;
};

/*
 * Interface request structure used for socket
 * ioctl's.  All interface ioctl's must have parameter
 * definitions which begin with ifr_name.  The
 * remainder may be interface specific.
 */
struct	ifreq {
	char	ifr_name[IFNAMSIZ];		/* if name, e.g. "en0" */
	union {
		struct	sockaddr ifru_addr;
		struct	sockaddr ifru_dstaddr;
		struct	sockaddr ifru_broadaddr;
		struct	ifreq_buffer ifru_buffer;
		short	ifru_flags[2];
		short	ifru_index;
		int	ifru_jid;
		int	ifru_metric;
		int	ifru_mtu;
		int	ifru_phys;
		int	ifru_media;
		caddr_t	ifru_data;
		int	ifru_cap[2];
		u_int	ifru_fib;
	} ifr_ifru;
#define	ifr_addr	ifr_ifru.ifru_addr	/* address */
#define	ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-to-p link */
#define	ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address */
#define	ifr_buffer	ifr_ifru.ifru_buffer	/* user supplied buffer with its length */
#define	ifr_flags	ifr_ifru.ifru_flags[0]	/* flags (low 16 bits) */
#define	ifr_flagshigh	ifr_ifru.ifru_flags[1]	/* flags (high 16 bits) */
#define	ifr_jid		ifr_ifru.ifru_jid	/* jail/vnet */
#define	ifr_metric	ifr_ifru.ifru_metric	/* metric */
#define	ifr_mtu		ifr_ifru.ifru_mtu	/* mtu */
#define ifr_phys	ifr_ifru.ifru_phys	/* physical wire */
#define ifr_media	ifr_ifru.ifru_media	/* physical media */
#define	ifr_data	ifr_ifru.ifru_data	/* for use by interface */
#define	ifr_reqcap	ifr_ifru.ifru_cap[0]	/* requested capabilities */
#define	ifr_curcap	ifr_ifru.ifru_cap[1]	/* current capabilities */
#define	ifr_index	ifr_ifru.ifru_index	/* interface index */
#define	ifr_fib		ifr_ifru.ifru_fib	/* interface fib */
};

#define	_SIZEOF_ADDR_IFREQ(ifr) \
	((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \
	 (sizeof(struct ifreq) - sizeof(struct sockaddr) + \
	  (ifr).ifr_addr.sa_len) : sizeof(struct ifreq))

struct ifaliasreq {
	char	ifra_name[IFNAMSIZ];		/* if name, e.g. "en0" */
	struct	sockaddr ifra_addr;
	struct	sockaddr ifra_broadaddr;
	struct	sockaddr ifra_mask;
};

struct ifmediareq {
	char	ifm_name[IFNAMSIZ];	/* if name, e.g. "en0" */
	int	ifm_current;		/* current media options */
	int	ifm_mask;		/* don't care mask */
	int	ifm_status;		/* media status */
	int	ifm_active;		/* active options */
	int	ifm_count;		/* # entries in ifm_ulist array */
	int	*ifm_ulist;		/* media words */
};

struct  ifdrv {
	char            ifd_name[IFNAMSIZ];     /* if name, e.g. "en0" */
	unsigned long   ifd_cmd;
	size_t          ifd_len;
	void            *ifd_data;
};

/*
 * Structure used to retrieve aux status data from interfaces.
 * Kernel suppliers to this interface should respect the formatting
 * needed by ifconfig(8): each line starts with a TAB and ends with
 * a newline.  The canonical example to copy and paste is in if_tun.c.
 */

#define	IFSTATMAX	800		/* 10 lines of text */
struct ifstat {
	char	ifs_name[IFNAMSIZ];	/* if name, e.g. "en0" */
	char	ascii[IFSTATMAX + 1];
};

/*
 * Structure used in SIOCGIFCONF request.
 * Used to retrieve interface configuration
 * for machine (useful for programs which
 * must know all networks accessible).
 */
struct	ifconf {
	int	ifc_len;		/* size of associated buffer */
	union {
		caddr_t	ifcu_buf;
		struct	ifreq *ifcu_req;
	} ifc_ifcu;
#define	ifc_buf	ifc_ifcu.ifcu_buf	/* buffer address */
#define	ifc_req	ifc_ifcu.ifcu_req	/* array of structures returned */
};

/*
 * interface groups
 */

#define	IFG_ALL		"all"		/* group contains all interfaces */
/* XXX: will we implement this? */
#define	IFG_EGRESS	"egress"	/* if(s) default route(s) point to */

struct ifg_req {
	union {
		char			 ifgrqu_group[IFNAMSIZ];
		char			 ifgrqu_member[IFNAMSIZ];
	} ifgrq_ifgrqu;
#define	ifgrq_group	ifgrq_ifgrqu.ifgrqu_group
#define	ifgrq_member	ifgrq_ifgrqu.ifgrqu_member
};

/*
 * Used to lookup groups for an interface
 */
struct ifgroupreq {
	char	ifgr_name[IFNAMSIZ];
	u_int	ifgr_len;
	union {
		char	ifgru_group[IFNAMSIZ];
		struct	ifg_req *ifgru_groups;
	} ifgr_ifgru;
#define ifgr_group	ifgr_ifgru.ifgru_group
#define ifgr_groups	ifgr_ifgru.ifgru_groups
};

/*
 * Structure for SIOC[AGD]LIFADDR
 */
struct if_laddrreq {
	char	iflr_name[IFNAMSIZ];
	u_int	flags;
#define	IFLR_PREFIX	0x8000  /* in: prefix given  out: kernel fills id */
	u_int	prefixlen;         /* in/out */
	struct	sockaddr_storage addr;   /* in/out */
	struct	sockaddr_storage dstaddr; /* out */
};

#endif /* __BSD_VISIBLE */

#ifdef _KERNEL
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_IFADDR);
MALLOC_DECLARE(M_IFMADDR);
#endif
#endif

#ifndef _KERNEL
struct if_nameindex {
	unsigned int	if_index;	/* 1, 2, ... */
	char		*if_name;	/* null terminated name: "le0", ... */
};

__BEGIN_DECLS
void			 if_freenameindex(struct if_nameindex *);
char			*if_indextoname(unsigned int, char *);
struct if_nameindex	*if_nameindex(void);
unsigned int		 if_nametoindex(const char *);
__END_DECLS
#endif

#ifdef _KERNEL
/* XXX - this should go away soon. */
#include <net/if_var.h>
#endif

#endif /* !_NET_IF_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*	$NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp $	*/
/* $FreeBSD: release/9.0.0/sys/net/if_arc.h 194581 2009-06-21 10:29:31Z rdivacky $ */

/*-
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.  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.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
 *
 * from: NetBSD: if_ether.h,v 1.10 1994/06/29 06:37:55 cgd Exp
 *       @(#)if_ether.h	8.1 (Berkeley) 6/10/93
 */

#ifndef _NET_IF_ARC_H_
#define _NET_IF_ARC_H_

/*
 * Arcnet address - 1 octets
 * don't know who uses this.
 */
struct arc_addr {
	u_int8_t  arc_addr_octet[1];
} __packed;

/*
 * Structure of a 2.5MB/s Arcnet header.
 * as given to interface code.
 */
struct	arc_header {
	u_int8_t  arc_shost;
	u_int8_t  arc_dhost;
	u_int8_t  arc_type;
	/*
	 * only present for newstyle encoding with LL fragmentation.
	 * Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead.
	 */
	u_int8_t  arc_flag;
	u_int16_t arc_seqid;

	/*
	 * only present in exception packets (arc_flag == 0xff)
	 */
	u_int8_t  arc_type2;	/* same as arc_type */
	u_int8_t  arc_flag2;	/* real flag value */
	u_int16_t arc_seqid2;	/* real seqid value */
} __packed;

#define	ARC_ADDR_LEN		1

#define	ARC_HDRLEN		3
#define	ARC_HDRNEWLEN		6
#define	ARC_HDRNEWLEN_EXC	10

/* these lengths are data link layer length - 2 * ARC_ADDR_LEN */
#define	ARC_MIN_LEN		1
#define	ARC_MIN_FORBID_LEN	254
#define	ARC_MAX_FORBID_LEN	256
#define	ARC_MAX_LEN		508
#define ARC_MAX_DATA		504

/* RFC 1051 */
#define	ARCTYPE_IP_OLD		240	/* IP protocol */
#define	ARCTYPE_ARP_OLD		241	/* address resolution protocol */

/* RFC 1201 */
#define	ARCTYPE_IP		212	/* IP protocol */
#define	ARCTYPE_ARP		213	/* address resolution protocol */
#define	ARCTYPE_REVARP		214	/* reverse addr resolution protocol */

#define	ARCTYPE_ATALK		221	/* Appletalk */
#define	ARCTYPE_BANIAN		247	/* Banyan Vines */
#define	ARCTYPE_IPX		250	/* Novell IPX */

#define ARCTYPE_INET6		0xc4	/* IPng */
#define ARCTYPE_DIAGNOSE	0x80	/* as per ANSI/ATA 878.1 */

#define	ARCMTU			507
#define	ARCMIN			0

#define ARC_PHDS_MAXMTU		60480

struct	arccom {
	struct	  ifnet *ac_ifp;	/* network-visible interface */

	u_int16_t ac_seqid;		/* seq. id used by PHDS encap. */

	u_int8_t  arc_shost;
	u_int8_t  arc_dhost;
	u_int8_t  arc_type;

	u_int8_t  dummy0;
	u_int16_t dummy1;
	int sflag, fsflag, rsflag;
	struct mbuf *curr_frag;

	struct ac_frag {
		u_int8_t  af_maxflag;	/* from first packet */
		u_int8_t  af_lastseen;	/* last split flag seen */
		u_int16_t af_seqid;
		struct mbuf *af_packet;
	} ac_fragtab[256];		/* indexed by sender ll address */
};

#ifdef _KERNEL
extern u_int8_t arcbroadcastaddr;
extern int arc_ipmtu;	/* XXX new ip only, no RFC 1051! */

void	arc_ifattach(struct ifnet *, u_int8_t);
void	arc_ifdetach(struct ifnet *);
void	arc_storelladdr(struct ifnet *, u_int8_t);
int	arc_isphds(u_int8_t);
void	arc_input(struct ifnet *, struct mbuf *);
int	arc_output(struct ifnet *, struct mbuf *,
	    struct sockaddr *, struct route *);
int	arc_ioctl(struct ifnet *, u_long, caddr_t);

void		arc_frag_init(struct ifnet *);
struct mbuf *	arc_frag_next(struct ifnet *);
#endif

#endif /* _NET_IF_ARC_H_ */


code:
/*-
 * Copyright (c) 1986, 1993
 *	The Regents of the University of California.  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.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
 *
 *	@(#)if_arp.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: release/9.0.0/sys/net/if_arp.h 219819 2011-03-21 09:40:01Z jeff $
 */

#ifndef _NET_IF_ARP_H_
#define	_NET_IF_ARP_H_

/*
 * Address Resolution Protocol.
 *
 * See RFC 826 for protocol description.  ARP packets are variable
 * in size; the arphdr structure defines the fixed-length portion.
 * Protocol type values are the same as those for 10 Mb/s Ethernet.
 * It is followed by the variable-sized fields ar_sha, arp_spa,
 * arp_tha and arp_tpa in that order, according to the lengths
 * specified.  Field names used correspond to RFC 826.
 */
struct	arphdr {
	u_short	ar_hrd;		/* format of hardware address */
#define ARPHRD_ETHER 	1	/* ethernet hardware format */
#define ARPHRD_IEEE802	6	/* token-ring hardware format */
#define ARPHRD_ARCNET	7	/* arcnet hardware format */
#define ARPHRD_FRELAY 	15	/* frame relay hardware format */
#define ARPHRD_IEEE1394	24	/* firewire hardware format */
#define ARPHRD_INFINIBAND 32	/* infiniband hardware format */
	u_short	ar_pro;		/* format of protocol address */
	u_char	ar_hln;		/* length of hardware address */
	u_char	ar_pln;		/* length of protocol address */
	u_short	ar_op;		/* one of: */
#define	ARPOP_REQUEST	1	/* request to resolve address */
#define	ARPOP_REPLY	2	/* response to previous request */
#define	ARPOP_REVREQUEST 3	/* request protocol address given hardware */
#define	ARPOP_REVREPLY	4	/* response giving protocol address */
#define ARPOP_INVREQUEST 8 	/* request to identify peer */
#define ARPOP_INVREPLY	9	/* response identifying peer */
/*
 * The remaining fields are variable in size,
 * according to the sizes above.
 */
#ifdef COMMENT_ONLY
	u_char	ar_sha[];	/* sender hardware address */
	u_char	ar_spa[];	/* sender protocol address */
	u_char	ar_tha[];	/* target hardware address */
	u_char	ar_tpa[];	/* target protocol address */
#endif
};

#define ar_sha(ap)	(((caddr_t)((ap)+1)) +   0)
#define ar_spa(ap)	(((caddr_t)((ap)+1)) +   (ap)->ar_hln)
#define ar_tha(ap)	(((caddr_t)((ap)+1)) +   (ap)->ar_hln + (ap)->ar_pln)
#define ar_tpa(ap)	(((caddr_t)((ap)+1)) + 2*(ap)->ar_hln + (ap)->ar_pln)

#define arphdr_len2(ar_hln, ar_pln)					\
	(sizeof(struct arphdr) + 2*(ar_hln) + 2*(ar_pln))
#define arphdr_len(ap)	(arphdr_len2((ap)->ar_hln, (ap)->ar_pln))

/*
 * ARP ioctl request
 */
struct arpreq {
	struct	sockaddr arp_pa;		/* protocol address */
	struct	sockaddr arp_ha;		/* hardware address */
	int	arp_flags;			/* flags */
};
/*  arp_flags and at_flags field values */
#define	ATF_INUSE	0x01	/* entry in use */
#define ATF_COM		0x02	/* completed entry (enaddr valid) */
#define	ATF_PERM	0x04	/* permanent entry */
#define	ATF_PUBL	0x08	/* publish entry (respond for other host) */
#define	ATF_USETRAILERS	0x10	/* has requested trailers */

#ifdef _KERNEL
/*
 * Structure shared between the ethernet driver modules and
 * the address resolution code.
 */
struct	arpcom {
	struct 	ifnet *ac_ifp;		/* network-visible interface */
	void	*ac_netgraph;		/* ng_ether(4) netgraph node info */
};
#define IFP2AC(ifp) ((struct arpcom *)(ifp->if_l2com))
#define AC2IFP(ac) ((ac)->ac_ifp)

#endif /* _KERNEL */

struct arpstat {
	/* Normal things that happen: */
	u_long txrequests;	/* # of ARP requests sent by this host. */
	u_long txreplies;	/* # of ARP replies sent by this host. */
	u_long rxrequests;	/* # of ARP requests received by this host. */
	u_long rxreplies;	/* # of ARP replies received by this host. */
	u_long received;	/* # of ARP packets received by this host. */

	u_long arp_spares[4];	/* For either the upper or lower half. */
	/* Abnormal event and error  counting: */
	u_long dropped;		/* # of packets dropped waiting for a reply. */
	u_long timeouts;	/* # of times with entries removed */
				/* due to timeout. */
	u_long dupips;		/* # of duplicate IPs detected. */
};

/*
 * In-kernel consumers can use these accessor macros directly to update
 * stats.
 */
#define	ARPSTAT_ADD(name, val)	V_arpstat.name += (val)
#define	ARPSTAT_SUB(name, val)	V_arpstat.name -= (val)
#define	ARPSTAT_INC(name)	ARPSTAT_ADD(name, 1)
#define	ARPSTAT_DEC(name)	ARPSTAT_SUB(name, 1)

#endif /* !_NET_IF_ARP_H_ */


code:
/*      $NetBSD: if_atm.h,v 1.7 1996/11/09 23:02:27 chuck Exp $       */
/* $FreeBSD: release/9.0.0/sys/net/if_atm.h 191148 2009-04-16 20:30:28Z kmacy $ */

/*-
 *
 * Copyright (c) 1996 Charles D. Cranor and Washington University.
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Charles D. Cranor and
 *	Washington University.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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.
 */

/*
 * net/if_atm.h
 */

/*
 * Classification of ATM cards.
 */
#define	ATM_DEVICE_UNKNOWN	0
#define	ATM_DEVICE_PCA200E	1	/* Fore/Marconi PCA200-E */
#define	ATM_DEVICE_HE155	2	/* Fore/Marconi HE155 */
#define	ATM_DEVICE_HE622	3	/* Fore/Marconi HE622 */
#define	ATM_DEVICE_ENI155P	4	/* Efficient networks 155p */
#define	ATM_DEVICE_ADP155P	5	/* Adaptec 155p */
#define	ATM_DEVICE_FORELE25	6	/* ForeRunnerLE 25 */
#define	ATM_DEVICE_FORELE155	7	/* ForeRunnerLE 155 */
#define	ATM_DEVICE_NICSTAR25	8	/* other 77211 25.6MBit */
#define	ATM_DEVICE_NICSTAR155	9	/* other 77211 155MBit */
#define	ATM_DEVICE_IDTABR25	10	/* 77252 based card 25MBit */
#define	ATM_DEVICE_IDTABR155	11	/* 77252 based card 155MBit */
#define	ATM_DEVICE_PROATM25	12	/* 77252 based ProSum card 25MBit */
#define	ATM_DEVICE_PROATM155	13	/* 77252 based ProSum card 155MBit */
#define	ATM_DEVICE_VIRTUAL	14	/* virtual ATM device (netgraph) */

/* map to strings and vendors */
#define	ATM_DEVICE_NAMES						\
	{ "Unknown",		"Unknown" },				\
	{ "PCA200-E",		"Fore/Marconi" },			\
	{ "HE155",		"Fore/Marconi" },			\
	{ "HE622",		"Fore/Marconi" },			\
	{ "ENI155p",		"Efficient Networks" },			\
	{ "ADP155p",		"Adaptec" },				\
	{ "ForeRunnerLE25",	"Fore/Marconi" },			\
	{ "ForeRunnerLE155",	"Fore/Marconi" },			\
	{ "IDT77211/25",	"IDT" },				\
	{ "IDT77211/155",	"IDT" },				\
	{ "IDT77252/25",	"IDT" },				\
	{ "IDT77252/155",	"IDT" },				\
	{ "ProATM/25",		"ProSum" },				\
	{ "ProATM/155",		"ProSum" },				\
	{ "Virtual",		"NetGraph" },

/*
 * This is the common link layer MIB for all ATM interfaces. Much of the
 * information here is needed for ILMI. This will be augmented by statistics
 * at some point.
 */
struct ifatm_mib {
	/* configuration data */
	uint8_t		device;		/* type of card */
	u_char		esi[6];		/* end system identifier (MAC) */
	uint32_t	serial;		/* card serial number */
	uint32_t	hw_version;	/* card version */
	uint32_t	sw_version;	/* firmware version (if any) */
	uint32_t	pcr;		/* supported peak cell rate */
	uint32_t	media;		/* physical media */
	uint8_t		vpi_bits;	/* number of used bits in VPI field */
	uint8_t		vci_bits;	/* number of used bits in VCI field */
	uint16_t	max_vpcs;	/* maximum number of VPCs */
	uint32_t	max_vccs;	/* maximum number of VCCs */
};

/*
 * Traffic parameters for ATM connections. This contains all parameters
 * to accomodate UBR, UBR+MCR, CBR, VBR and ABR connections.
 *
 * Keep in sync with ng_atm.h
 */
struct atmio_tparam {
	uint32_t	pcr;	/* 24bit: Peak Cell Rate */
	uint32_t	scr;	/* 24bit: VBR Sustainable Cell Rate */
	uint32_t	mbs;	/* 24bit: VBR Maximum burst size */
	uint32_t	mcr;	/* 24bit: ABR/VBR/UBR+MCR MCR */
	uint32_t	icr;	/* 24bit: ABR ICR */
	uint32_t	tbe;	/* 24bit: ABR TBE (1...2^24-1) */
	uint8_t		nrm;	/*  3bit: ABR Nrm */
	uint8_t		trm;	/*  3bit: ABR Trm */
	uint16_t	adtf;	/* 10bit: ABR ADTF */
	uint8_t		rif;	/*  4bit: ABR RIF */
	uint8_t		rdf;	/*  4bit: ABR RDF */
	uint8_t		cdf;	/*  3bit: ABR CDF */
};

/*
 * VCC parameters
 *
 * Keep in sync with ng_atm.h
 */
struct atmio_vcc {
	uint16_t	flags;		/* VCC flags */
	uint16_t	vpi;
	uint16_t	vci;
	uint16_t	rmtu;		/* maximum receive PDU */
	uint16_t	tmtu;		/* maximum transmit PDU */
	uint8_t		aal;		/* aal type */
	uint8_t		traffic;	/* traffic type */
	struct atmio_tparam tparam;	/* traffic parameters */
};

/* VCC flags */
#define	ATMIO_FLAG_LLCSNAP	0x0002	/* same as ATM_PH_LLCSNAP */
#define	ATMIO_FLAG_NG		0x0010	/* owned by netgraph */
#define	ATMIO_FLAG_HARP		0x0020	/* owned by HARP */
#define	ATMIO_FLAG_NORX		0x0100	/* not receiving on this VCC */
#define	ATMIO_FLAG_NOTX		0x0200	/* not transmitting on this VCC */
#define	ATMIO_FLAG_PVC		0x0400	/* this is a PVC */
#define	ATMIO_FLAG_ASYNC	0x0800	/* async open/close */
#define	ATMIO_FLAGS	"\020\2LLCSNAP\5NG\6HARP\11NORX\12NOTX\13PVC\14ASYNC"

#define	ATMIO_AAL_0		0	/* pure cells */
#define	ATMIO_AAL_34		4	/* AAL3 and 4 */
#define	ATMIO_AAL_5		5	/* AAL5 */
#define	ATMIO_AAL_RAW		10	/* whatever the card does */

#define	ATMIO_TRAFFIC_UBR	0
#define	ATMIO_TRAFFIC_CBR	1
#define	ATMIO_TRAFFIC_ABR	2
#define	ATMIO_TRAFFIC_VBR	3

/*
 * VCC table
 *
 * Keep in sync with ng_atm.h
 */
struct atmio_vcctable {
	uint32_t	count;		/* number of vccs */
	struct atmio_vcc vccs[0];	/* array of VCCs */
};

/*
 * Peak cell rates for various physical media. Note, that there are
 * different opinions on what the correct values are.
 */
#define	ATM_RATE_25_6M		59259
#define	ATM_RATE_155M		353208
#define	ATM_RATE_622M		1412830
#define	ATM_RATE_2_4G		5651320

#ifdef _KERNEL
/*
 * Common fields for all ATM interfaces. Each driver's softc must start with
 * this structure.
 */
struct ifatm {
	struct ifnet	*ifp;
	struct ifatm_mib mib;		/* exported data */
	void		*phy;		/* usually SUNI */
	void		*ngpriv;	/* netgraph link */
};
#define	IFP2IFATM(ifp)	((struct ifatm *)(ifp)->if_l2com)
#endif

/*
 * Keep structures in sync with ng_atm.h
 *
 * These are used by netgraph/harp to call the driver
 * NATM uses the atm_pseudoioctl instead.
 */
struct atmio_openvcc {
	void		*rxhand;	/* handle argument */
	struct atmio_vcc param;		/* parameters */
};

struct atmio_closevcc {
	uint16_t	vpi;
	uint16_t	vci;
};

#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
#define	RTALLOC1(A,B)		rtalloc1((A),(B))
#elif defined(__FreeBSD__)
#define	RTALLOC1(A,B)		rtalloc1((A),(B),0UL)
#endif

/*
 * pseudo header for packet transmission
 */
struct atm_pseudohdr {
	uint8_t		atm_ph[4];	/* flags+VPI+VCI1(msb)+VCI2(lsb) */
};

#define	ATM_PH_FLAGS(X)	((X)->atm_ph[0])
#define	ATM_PH_VPI(X)	((X)->atm_ph[1])
#define	ATM_PH_VCI(X)	((((X)->atm_ph[2]) << 8) | ((X)->atm_ph[3]))
#define	ATM_PH_SETVCI(X,V) { \
	(X)->atm_ph[2] = ((V) >> 8) & 0xff; \
	(X)->atm_ph[3] = ((V) & 0xff); \
}

/* use AAL5? (0 == aal0) */
#define	ATM_PH_AAL5	0x01
/* use the LLC SNAP encoding (iff aal5) */
#define	ATM_PH_LLCSNAP ATMIO_FLAG_LLCSNAP

#define	ATM_PH_DRIVER7  0x40	/* reserve for driver's use */
#define	ATM_PH_DRIVER8  0x80	/* reserve for driver's use */

#define	ATMMTU		9180	/* ATM MTU size for IP */
				/* XXX: could be 9188 with LLC/SNAP according
					to comer */

#define	SIOCATMGETVCCS	_IOW('a', 125, struct atmio_vcctable)
#define	SIOCATMOPENVCC	_IOR('a', 126, struct atmio_openvcc)
#define	SIOCATMCLOSEVCC _IOR('a', 127, struct atmio_closevcc)

#define	SIOCATMGVCCS	_IOWR('i', 230, struct ifreq)

/*
 * XXX forget all the garbage in if_llc.h and do it the easy way
 */
#define	ATMLLC_HDR "\252\252\3\0\0\0"
struct atmllc {
	uint8_t		llchdr[6];	/* aa.aa.03.00.00.00 */
	uint8_t		type[2];	/* "ethernet" type */
};

/* ATM_LLC macros: note type code in host byte order */
#define	ATM_LLC_TYPE(X) (((X)->type[0] << 8) | ((X)->type[1]))
#define	ATM_LLC_SETTYPE(X, V) do {		\
	(X)->type[0] = ((V) >> 8) & 0xff;	\
	(X)->type[1] = ((V) & 0xff);		\
    } while (0)

/*
 * Events that are emitted by the driver. Currently the only consumer
 * of this is the netgraph node.
 */
#define	ATMEV_FLOW_CONTROL	0x0001	/* channel busy state changed */
#define	ATMEV_IFSTATE_CHANGED	0x0002	/* up/down or carrier */
#define	ATMEV_VCC_CHANGED	0x0003	/* PVC deleted/create */
#define	ATMEV_ACR_CHANGED	0x0004	/* ABR ACR has changed */

struct atmev_flow_control {
	uint16_t	vpi;		/* channel that is changed */
	uint16_t	vci;
	u_int		busy : 1;	/* != 0 -> ATM layer busy */
};

struct atmev_ifstate_changed {
	u_int		running : 1;	/* interface is running now */
	u_int		carrier : 1;	/* carrier detected (or not) */
};

struct atmev_vcc_changed {
	uint16_t	vpi;		/* channel that is changed */
	uint16_t	vci;
	u_int		up : 1;		/* 1 - created, 0 - deleted */
};

struct atmev_acr_changed {
	uint16_t	vpi;		/* channel that is changed */
	uint16_t	vci;
	uint32_t	acr;		/* new ACR */
};

#ifdef _KERNEL
void	atm_ifattach(struct ifnet *);
void	atm_ifdetach(struct ifnet *);
void	atm_input(struct ifnet *, struct atm_pseudohdr *,
	    struct mbuf *, void *);
int	atm_output(struct ifnet *, struct mbuf *, struct sockaddr *,
	    struct route *);
struct atmio_vcctable *atm_getvccs(struct atmio_vcc **, u_int, u_int,
	    struct mtx *, int);

void	atm_event(struct ifnet *, u_int, void *);

#define	ATMEV_SEND_FLOW_CONTROL(ATMIF, VPI, VCI, BUSY)			\
	do {								\
		struct atmev_flow_control _arg;				\
		_arg.vpi = (VPI);					\
		_arg.vci = (VCI);					\
		_arg.busy = (BUSY);					\
		atm_event((ATMIF)->ifp, ATMEV_FLOW_CONTROL, &_arg);	\
	} while (0)

#define	ATMEV_SEND_VCC_CHANGED(ATMIF, VPI, VCI, UP)			\
	do {								\
		struct atmev_vcc_changed _arg;				\
		_arg.vpi = (VPI);					\
		_arg.vci = (VCI);					\
		_arg.up = (UP);						\
		atm_event((ATMIF)->ifp, ATMEV_VCC_CHANGED, &_arg);	\
	} while (0)

#define	ATMEV_SEND_IFSTATE_CHANGED(ATMIF, CARRIER)			\
	do {								\
		struct atmev_ifstate_changed _arg;			\
		_arg.running = (((ATMIF)->ifp->if_drv_flags &		\
		    IFF_DRV_RUNNING) != 0);				\
		_arg.carrier = ((CARRIER) != 0);			\
		atm_event((ATMIF)->ifp, ATMEV_IFSTATE_CHANGED, &_arg); \
	} while (0)

#define	ATMEV_SEND_ACR_CHANGED(ATMIF, VPI, VCI, ACR)			\
	do {								\
		struct atmev_acr_changed _arg;				\
		_arg.vpi = (VPI);					\
		_arg.vci = (VCI);					\
		_arg.acr= (ACR);					\
		atm_event((ATMIF)->ifp, ATMEV_ACR_CHANGED, &_arg);	\
	} while (0)
#endif


code:
/*	$NetBSD: if_bridgevar.h,v 1.4 2003/07/08 07:13:50 itojun Exp $	*/

/*
 * Copyright 2001 Wasabi Systems, Inc.
 * All rights reserved.
 *
 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
 *
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed for the NetBSD Project by
 *	Wasabi Systems, Inc.
 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
 *    or promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
 * 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.
 */

/*
 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Jason L. Wright
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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.
 *
 * OpenBSD: if_bridge.h,v 1.14 2001/03/22 03:48:29 jason Exp
 *
 * $FreeBSD: release/9.0.0/sys/net/if_bridgevar.h 173320 2007-11-04 08:32:27Z thompsa $
 */

/*
 * Data structure and control definitions for bridge interfaces.
 */

#include <sys/callout.h>
#include <sys/queue.h>
#include <sys/condvar.h>

/*
 * Commands used in the SIOCSDRVSPEC ioctl.  Note the lookup of the
 * bridge interface itself is keyed off the ifdrv structure.
 */
#define	BRDGADD			0	/* add bridge member (ifbreq) */
#define	BRDGDEL			1	/* delete bridge member (ifbreq) */
#define	BRDGGIFFLGS		2	/* get member if flags (ifbreq) */
#define	BRDGSIFFLGS		3	/* set member if flags (ifbreq) */
#define	BRDGSCACHE		4	/* set cache size (ifbrparam) */
#define	BRDGGCACHE		5	/* get cache size (ifbrparam) */
#define	BRDGGIFS		6	/* get member list (ifbifconf) */
#define	BRDGRTS			7	/* get address list (ifbaconf) */
#define	BRDGSADDR		8	/* set static address (ifbareq) */
#define	BRDGSTO			9	/* set cache timeout (ifbrparam) */
#define	BRDGGTO			10	/* get cache timeout (ifbrparam) */
#define	BRDGDADDR		11	/* delete address (ifbareq) */
#define	BRDGFLUSH		12	/* flush address cache (ifbreq) */

#define	BRDGGPRI		13	/* get priority (ifbrparam) */
#define	BRDGSPRI		14	/* set priority (ifbrparam) */
#define	BRDGGHT			15	/* get hello time (ifbrparam) */
#define	BRDGSHT			16	/* set hello time (ifbrparam) */
#define	BRDGGFD			17	/* get forward delay (ifbrparam) */
#define	BRDGSFD			18	/* set forward delay (ifbrparam) */
#define	BRDGGMA			19	/* get max age (ifbrparam) */
#define	BRDGSMA			20	/* set max age (ifbrparam) */
#define	BRDGSIFPRIO		21	/* set if priority (ifbreq) */
#define	BRDGSIFCOST		22	/* set if path cost (ifbreq) */
#define	BRDGADDS		23	/* add bridge span member (ifbreq) */
#define	BRDGDELS		24	/* delete bridge span member (ifbreq) */
#define	BRDGPARAM		25	/* get bridge STP params (ifbropreq) */
#define	BRDGGRTE		26	/* get cache drops (ifbrparam) */
#define	BRDGGIFSSTP		27	/* get member STP params list
					 * (ifbpstpconf) */
#define	BRDGSPROTO		28	/* set protocol (ifbrparam) */
#define	BRDGSTXHC		29	/* set tx hold count (ifbrparam) */
#define	BRDGSIFAMAX		30	/* set max interface addrs (ifbreq) */

/*
 * Generic bridge control request.
 */
struct ifbreq {
	char		ifbr_ifsname[IFNAMSIZ];	/* member if name */
	uint32_t	ifbr_ifsflags;		/* member if flags */
	uint32_t	ifbr_stpflags;		/* member if STP flags */
	uint32_t	ifbr_path_cost;		/* member if STP cost */
	uint8_t		ifbr_portno;		/* member if port number */
	uint8_t		ifbr_priority;		/* member if STP priority */
	uint8_t		ifbr_proto;		/* member if STP protocol */
	uint8_t		ifbr_role;		/* member if STP role */
	uint8_t		ifbr_state;		/* member if STP state */
	uint32_t	ifbr_addrcnt;		/* member if addr number */
	uint32_t	ifbr_addrmax;		/* member if addr max */
	uint32_t	ifbr_addrexceeded;	/* member if addr violations */
	uint8_t		pad[32];
};

/* BRDGGIFFLAGS, BRDGSIFFLAGS */
#define	IFBIF_LEARNING		0x0001	/* if can learn */
#define	IFBIF_DISCOVER		0x0002	/* if sends packets w/ unknown dest. */
#define	IFBIF_STP		0x0004	/* if participates in spanning tree */
#define	IFBIF_SPAN		0x0008	/* if is a span port */
#define	IFBIF_STICKY		0x0010	/* if learned addresses stick */
#define	IFBIF_BSTP_EDGE		0x0020	/* member stp edge port */
#define	IFBIF_BSTP_AUTOEDGE	0x0040	/* member stp autoedge enabled */
#define	IFBIF_BSTP_PTP		0x0080	/* member stp point to point */
#define	IFBIF_BSTP_AUTOPTP	0x0100	/* member stp autoptp enabled */
#define	IFBIF_BSTP_ADMEDGE	0x0200	/* member stp admin edge enabled */
#define	IFBIF_BSTP_ADMCOST	0x0400	/* member stp admin path cost */
#define	IFBIF_PRIVATE		0x0800	/* if is a private segment */

#define	IFBIFBITS	"\020\001LEARNING\002DISCOVER\003STP\004SPAN" \
			"\005STICKY\014PRIVATE\006EDGE\007AUTOEDGE\010PTP" \
			"\011AUTOPTP"
#define	IFBIFMASK	~(IFBIF_BSTP_EDGE|IFBIF_BSTP_AUTOEDGE|IFBIF_BSTP_PTP| \
			IFBIF_BSTP_AUTOPTP|IFBIF_BSTP_ADMEDGE| \
			IFBIF_BSTP_ADMCOST)	/* not saved */

/* BRDGFLUSH */
#define	IFBF_FLUSHDYN		0x00	/* flush learned addresses only */
#define	IFBF_FLUSHALL		0x01	/* flush all addresses */

/*
 * Interface list structure.
 */
struct ifbifconf {
	uint32_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_ifsname[IFNAMSIZ];	/* member if name */
	unsigned long	ifba_expire;		/* address expire time */
	uint8_t		ifba_flags;		/* address flags */
	uint8_t		ifba_dst[ETHER_ADDR_LEN];/* destination address */
	uint16_t	ifba_vlan;		/* vlan id */
};

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

#define	IFBAFBITS	"\020\1STATIC\2STICKY"

/*
 * Address list structure.
 */
struct ifbaconf {
	uint32_t	ifbac_len;	/* buffer size */
	union {
		caddr_t ifbacu_buf;
		struct ifbareq *ifbacu_req;
	} ifbac_ifbacu;
#define	ifbac_buf	ifbac_ifbacu.ifbacu_buf
#define	ifbac_req	ifbac_ifbacu.ifbacu_req
};

/*
 * Bridge parameter structure.
 */
struct ifbrparam {
	union {
		uint32_t ifbrpu_int32;
		uint16_t ifbrpu_int16;
		uint8_t ifbrpu_int8;
	} ifbrp_ifbrpu;
};
#define	ifbrp_csize	ifbrp_ifbrpu.ifbrpu_int32	/* cache size */
#define	ifbrp_ctime	ifbrp_ifbrpu.ifbrpu_int32	/* cache time (sec) */
#define	ifbrp_prio	ifbrp_ifbrpu.ifbrpu_int16	/* bridge priority */
#define	ifbrp_proto	ifbrp_ifbrpu.ifbrpu_int8	/* bridge protocol */
#define	ifbrp_txhc	ifbrp_ifbrpu.ifbrpu_int8	/* bpdu tx holdcount */
#define	ifbrp_hellotime	ifbrp_ifbrpu.ifbrpu_int8	/* hello time (sec) */
#define	ifbrp_fwddelay	ifbrp_ifbrpu.ifbrpu_int8	/* fwd time (sec) */
#define	ifbrp_maxage	ifbrp_ifbrpu.ifbrpu_int8	/* max age (sec) */
#define	ifbrp_cexceeded ifbrp_ifbrpu.ifbrpu_int32	/* # of cache dropped
							 * adresses */
/*
 * Bridge current operational parameters structure.
 */
struct ifbropreq {
	uint8_t		ifbop_holdcount;
	uint8_t		ifbop_maxage;
	uint8_t		ifbop_hellotime;
	uint8_t		ifbop_fwddelay;
	uint8_t		ifbop_protocol;
	uint16_t	ifbop_priority;
	uint16_t	ifbop_root_port;
	uint32_t	ifbop_root_path_cost;
	uint64_t	ifbop_bridgeid;
	uint64_t	ifbop_designated_root;
	uint64_t	ifbop_designated_bridge;
	struct timeval	ifbop_last_tc_time;
};

/*
 * Bridge member operational STP params structure.
 */
struct ifbpstpreq {
	uint8_t		ifbp_portno;		/* bp STP port number */
	uint32_t	ifbp_fwd_trans;		/* bp STP fwd transitions */
	uint32_t	ifbp_design_cost;	/* bp STP designated cost */
	uint32_t	ifbp_design_port;	/* bp STP designated port */
	uint64_t	ifbp_design_bridge;	/* bp STP designated bridge */
	uint64_t	ifbp_design_root;	/* bp STP designated root */
};

/*
 * Bridge STP ports list structure.
 */
struct ifbpstpconf {
	uint32_t	ifbpstp_len;	/* buffer size */
	union {
		caddr_t	ifbpstpu_buf;
		struct ifbpstpreq *ifbpstpu_req;
	} ifbpstp_ifbpstpu;
#define	ifbpstp_buf	ifbpstp_ifbpstpu.ifbpstpu_buf
#define	ifbpstp_req	ifbpstp_ifbpstpu.ifbpstpu_req
};

#ifdef _KERNEL

#define BRIDGE_LOCK_INIT(_sc)		do {			\
	mtx_init(&(_sc)->sc_mtx, "if_bridge", NULL, MTX_DEF);	\
	cv_init(&(_sc)->sc_cv, "if_bridge_cv");			\
} while (0)
#define BRIDGE_LOCK_DESTROY(_sc)	do {	\
	mtx_destroy(&(_sc)->sc_mtx);		\
	cv_destroy(&(_sc)->sc_cv);		\
} while (0)
#define BRIDGE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
#define BRIDGE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
#define BRIDGE_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
#define	BRIDGE_LOCK2REF(_sc, _err)	do {	\
	mtx_assert(&(_sc)->sc_mtx, MA_OWNED);	\
	if ((_sc)->sc_iflist_xcnt > 0)		\
		(_err) = EBUSY;			\
	else					\
		(_sc)->sc_iflist_ref++;		\
	mtx_unlock(&(_sc)->sc_mtx);		\
} while (0)
#define	BRIDGE_UNREF(_sc)		do {				\
	mtx_lock(&(_sc)->sc_mtx);					\
	(_sc)->sc_iflist_ref--;						\
	if (((_sc)->sc_iflist_xcnt > 0) && ((_sc)->sc_iflist_ref == 0))	\
		cv_broadcast(&(_sc)->sc_cv);				\
	mtx_unlock(&(_sc)->sc_mtx);					\
} while (0)
#define	BRIDGE_XLOCK(_sc)		do {		\
	mtx_assert(&(_sc)->sc_mtx, MA_OWNED);		\
	(_sc)->sc_iflist_xcnt++;			\
	while ((_sc)->sc_iflist_ref > 0)		\
		cv_wait(&(_sc)->sc_cv, &(_sc)->sc_mtx);	\
} while (0)
#define	BRIDGE_XDROP(_sc)		do {	\
	mtx_assert(&(_sc)->sc_mtx, MA_OWNED);	\
	(_sc)->sc_iflist_xcnt--;		\
} while (0)

#define BRIDGE_INPUT(_ifp, _m)		do {    	\
	KASSERT(bridge_input_p != NULL,			\
	    ("%s: if_bridge not loaded!", __func__));	\
	_m = (*bridge_input_p)(_ifp, _m);		\
	if (_m != NULL)					\
		_ifp = _m->m_pkthdr.rcvif;		\
} while (0)

#define BRIDGE_OUTPUT(_ifp, _m, _err)	do {    		\
	KASSERT(bridge_output_p != NULL,			\
	    ("%s: if_bridge not loaded!", __func__));		\
	_err = (*bridge_output_p)(_ifp, _m, NULL, NULL);	\
} while (0)

extern	struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *);
extern	int (*bridge_output_p)(struct ifnet *, struct mbuf *,
		struct sockaddr *, struct rtentry *);
extern	void (*bridge_dn_p)(struct mbuf *, struct ifnet *);

#endif /* _KERNEL */


code:
/*-
 * Copyright (c) 1982, 1986, 1989, 1993
 *	The Regents of the University of California.  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.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
 *
 *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: release/9.0.0/sys/net/if_clone.h 195837 2009-07-23 20:46:49Z rwatson $
 */

#ifndef	_NET_IF_CLONE_H_
#define	_NET_IF_CLONE_H_

#ifdef _KERNEL

#define IFC_CLONE_INITIALIZER(name, data, maxunit,			\
    attach, match, create, destroy)					\
    { { 0 }, name, maxunit, NULL, 0, data, attach, match, create, destroy }

/*
 * Structure describing a `cloning' interface.
 *
 * List of locks
 * (c)		const until freeing
 * (d)		driver specific data, may need external protection.
 * (e)		locked by if_cloners_mtx
 * (i)		locked by ifc_mtx mtx
 */
struct if_clone {
	LIST_ENTRY(if_clone) ifc_list;	/* (e) On list of cloners */
	const char *ifc_name;		/* (c) Name of device, e.g. `gif' */
	int ifc_maxunit;		/* (c) Maximum unit number */
	unsigned char *ifc_units;	/* (i) Bitmap to handle units. */
					/*     Considered private, access */
					/*     via ifc_(alloc|free)_unit(). */
	int ifc_bmlen;			/* (c) Bitmap length. */
	void *ifc_data;			/* (*) Data for ifc_* functions. */

	/* (c) Driver specific cloning functions.  Called with no locks held. */
	void	(*ifc_attach)(struct if_clone *);
	int	(*ifc_match)(struct if_clone *, const char *);
	int	(*ifc_create)(struct if_clone *, char *, size_t, caddr_t);
	int	(*ifc_destroy)(struct if_clone *, struct ifnet *);

	long ifc_refcnt;		/* (i) Refrence count. */
	struct mtx ifc_mtx;		/* Muted to protect members. */
	LIST_HEAD(, ifnet) ifc_iflist;	/* (i) List of cloned interfaces */
};

void	if_clone_init(void);
void	if_clone_attach(struct if_clone *);
void	if_clone_detach(struct if_clone *);
void	vnet_if_clone_init(void);

int	if_clone_create(char *, size_t, caddr_t);
int	if_clone_destroy(const char *);
int	if_clone_destroyif(struct if_clone *, struct ifnet *);
int	if_clone_list(struct if_clonereq *);

int	ifc_name2unit(const char *name, int *unit);
int	ifc_alloc_unit(struct if_clone *, int *);
void	ifc_free_unit(struct if_clone *, int);

/*
 * The ifc_simple functions, structures, and macros implement basic
 * cloning as in 5.[012].
 */

struct ifc_simple_data {
	int ifcs_minifs;		/* minimum number of interfaces */

	int	(*ifcs_create)(struct if_clone *, int, caddr_t);
	void	(*ifcs_destroy)(struct ifnet *);
};

/* interface clone event */
typedef void (*if_clone_event_handler_t)(void *, struct if_clone *);
EVENTHANDLER_DECLARE(if_clone_event, if_clone_event_handler_t);

#define IFC_SIMPLE_DECLARE(name, minifs)				\
struct ifc_simple_data name##_cloner_data =				\
    {minifs, name##_clone_create, name##_clone_destroy};		\
struct if_clone name##_cloner =						\
    IFC_CLONE_INITIALIZER(#name, &name##_cloner_data, IF_MAXUNIT,	\
    ifc_simple_attach, ifc_simple_match, ifc_simple_create, ifc_simple_destroy)

void	ifc_simple_attach(struct if_clone *);
int	ifc_simple_match(struct if_clone *, const char *);
int	ifc_simple_create(struct if_clone *, char *, size_t, caddr_t);
int	ifc_simple_destroy(struct if_clone *, struct ifnet *);

#endif /* _KERNEL */

#endif /* !_NET_IF_CLONE_H_ */


code:
/*-
 * Copyright (c) 1990, 1993
 *	The Regents of the University of California.  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.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
 *
 *	@(#)if_dl.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: release/9.0.0/sys/net/if_dl.h 139823 2005-01-07 01:45:51Z imp $
 */

#ifndef _NET_IF_DL_H_
#define _NET_IF_DL_H_

/*
 * A Link-Level Sockaddr may specify the interface in one of two
 * ways: either by means of a system-provided index number (computed
 * anew and possibly differently on every reboot), or by a human-readable
 * string such as "il0" (for managerial convenience).
 *
 * Census taking actions, such as something akin to SIOCGCONF would return
 * both the index and the human name.
 *
 * High volume transactions (such as giving a link-level ``from'' address
 * in a recvfrom or recvmsg call) may be likely only to provide the indexed
 * form, (which requires fewer copy operations and less space).
 *
 * The form and interpretation  of the link-level address is purely a matter
 * of convention between the device driver and its consumers; however, it is
 * expected that all drivers for an interface of a given if_type will agree.
 */

/*
 * Structure of a Link-Level sockaddr:
 */
struct sockaddr_dl {
	u_char	sdl_len;	/* Total length of sockaddr */
	u_char	sdl_family;	/* AF_LINK */
	u_short	sdl_index;	/* if != 0, system given index for interface */
	u_char	sdl_type;	/* interface type */
	u_char	sdl_nlen;	/* interface name length, no trailing 0 reqd. */
	u_char	sdl_alen;	/* link level address length */
	u_char	sdl_slen;	/* link layer selector length */
	char	sdl_data[46];	/* minimum work area, can be larger;
				   contains both if name and ll address */
};

#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))

#ifndef _KERNEL

#include <sys/cdefs.h>

__BEGIN_DECLS
void	link_addr(const char *, struct sockaddr_dl *);
char	*link_ntoa(const struct sockaddr_dl *);
__END_DECLS

#endif /* !_KERNEL */

#endif


code:
/*-
 * Copyright (c) 2008 The FreeBSD Project.
 * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
 *
 * $FreeBSD: release/9.0.0/sys/net/if_enc.h 181627 2008-08-12 09:05:01Z vanhu $
 */

#ifndef _NET_IF_ENC_H
#define _NET_IF_ENC_H

extern struct ifnet	*encif;

#endif /* _NET_IF_ENC_H */


code:
/*	$FreeBSD: release/9.0.0/sys/net/if_gif.h 207369 2010-04-29 11:52:42Z bz $	*/
/*	$KAME: if_gif.h,v 1.17 2000/09/11 11:36:41 sumikawa Exp $	*/

/*-
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 * 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.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
 */

/*
 * if_gif.h
 */

#ifndef _NET_IF_GIF_H_
#define _NET_IF_GIF_H_

#ifdef _KERNEL
#include "opt_inet.h"
#include "opt_inet6.h"

#include <netinet/in.h>
/* xxx sigh, why route have struct route instead of pointer? */

struct encaptab;

extern	void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp,
		int af);
extern	void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m,
		int af);
extern	int  (*ng_gif_output_p)(struct ifnet *ifp, struct mbuf **mp);
extern	void (*ng_gif_attach_p)(struct ifnet *ifp);
extern	void (*ng_gif_detach_p)(struct ifnet *ifp);

struct gif_softc {
	struct ifnet	*gif_ifp;
	struct mtx	gif_mtx;
	struct sockaddr	*gif_psrc; /* Physical src addr */
	struct sockaddr	*gif_pdst; /* Physical dst addr */
	union {
		struct route  gifscr_ro;    /* xxx */
#ifdef INET6
		struct route_in6 gifscr_ro6; /* xxx */
#endif
	} gifsc_gifscr;
	int		gif_flags;
	u_int		gif_fibnum;
	const struct encaptab *encap_cookie4;
	const struct encaptab *encap_cookie6;
	void		*gif_netgraph;	/* ng_gif(4) netgraph node info */
	u_int		gif_options;
	LIST_ENTRY(gif_softc) gif_list; /* all gif's are linked */
};
#define	GIF2IFP(sc)	((sc)->gif_ifp)
#define	GIF_LOCK_INIT(sc)	mtx_init(&(sc)->gif_mtx, "gif softc",	\
				     NULL, MTX_DEF)
#define	GIF_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->gif_mtx)
#define	GIF_LOCK(sc)		mtx_lock(&(sc)->gif_mtx)
#define	GIF_UNLOCK(sc)		mtx_unlock(&(sc)->gif_mtx)
#define	GIF_LOCK_ASSERT(sc)	mtx_assert(&(sc)->gif_mtx, MA_OWNED)

#define gif_ro gifsc_gifscr.gifscr_ro
#ifdef INET6
#define gif_ro6 gifsc_gifscr.gifscr_ro6
#endif

#define GIF_MTU		(1280)	/* Default MTU */
#define	GIF_MTU_MIN	(1280)	/* Minimum MTU */
#define	GIF_MTU_MAX	(8192)	/* Maximum MTU */

#define	MTAG_GIF	1080679712
#define	MTAG_GIF_CALLED	0

struct etherip_header {
#if BYTE_ORDER == LITTLE_ENDIAN
	u_int	eip_resvl:4,	/* reserved */
		eip_ver:4;	/* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN
	u_int	eip_ver:4,	/* version */
		eip_resvl:4;	/* reserved */
#endif
	u_int8_t eip_resvh;	/* reserved */
} __packed;

#define ETHERIP_VERSION			0x3
/* mbuf adjust factor to force 32-bit alignment of IP header */
#define	ETHERIP_ALIGN		2

/* Prototypes */
void gif_input(struct mbuf *, int, struct ifnet *);
int gif_output(struct ifnet *, struct mbuf *, struct sockaddr *,
	       struct route *);
int gif_ioctl(struct ifnet *, u_long, caddr_t);
int gif_set_tunnel(struct ifnet *, struct sockaddr *, struct sockaddr *);
void gif_delete_tunnel(struct ifnet *);
int gif_encapcheck(const struct mbuf *, int, int, void *);
#endif /* _KERNEL */

#define GIFGOPTS	_IOWR('i', 150, struct ifreq)
#define GIFSOPTS	_IOW('i', 151, struct ifreq)

#define	GIF_ACCEPT_REVETHIP	0x0001
#define	GIF_SEND_REVETHIP	0x0010
#define	GIF_OPTMASK		(GIF_ACCEPT_REVETHIP|GIF_SEND_REVETHIP)

#endif /* _NET_IF_GIF_H_ */


code:
/*	$NetBSD: if_gre.h,v 1.13 2003/11/10 08:51:52 wiz Exp $ */
/*	 $FreeBSD: release/9.0.0/sys/net/if_gre.h 223223 2011-06-18 09:34:03Z bz $ */

/*-
 * Copyright (c) 1998 The NetBSD Foundation, Inc.
 * All rights reserved
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Heiko W.Rupp <hwr@pilhuhn.de>
 *
 * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``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 FOUNDATION OR CONTRIBUTORS
 * 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.
 */

#ifndef _NET_IF_GRE_H
#define _NET_IF_GRE_H

#include <sys/ioccom.h>
#ifdef _KERNEL
#include <sys/queue.h>

/*
 * Version of the WCCP, need to be configured manually since
 * header for version 2 is the same but IP payload is prepended
 * with additional 4-bytes field.
 */
typedef enum {
	WCCP_V1 = 0,
	WCCP_V2
} wccp_ver_t;

struct gre_softc {
	struct ifnet *sc_ifp;
	LIST_ENTRY(gre_softc) sc_list;
	int gre_unit;
	int gre_flags;
	u_int	gre_fibnum;	/* use this fib for envelopes */
	struct in_addr g_src;	/* source address of gre packets */
	struct in_addr g_dst;	/* destination address of gre packets */
	struct route route;	/* routing entry that determines, where a
				   encapsulated packet should go */
	u_char g_proto;		/* protocol of encapsulator */

	const struct encaptab *encap;	/* encapsulation cookie */

	uint32_t key;		/* key included in outgoing GRE packets */
				/* zero means none */

	wccp_ver_t wccp_ver;	/* version of the WCCP */
};
#define	GRE2IFP(sc)	((sc)->sc_ifp)

struct gre_h {
	u_int16_t flags;	/* GRE flags */
	u_int16_t ptype;	/* protocol type of payload typically
				   Ether protocol type*/
	uint32_t options[0];	/* optional options */
/*
 *  from here on: fields are optional, presence indicated by flags
 *
	u_int_16 checksum	checksum (one-complements of GRE header
				and payload
				Present if (ck_pres | rt_pres == 1).
				Valid if (ck_pres == 1).
	u_int_16 offset		offset from start of routing filed to
				first octet of active SRE (see below).
				Present if (ck_pres | rt_pres == 1).
				Valid if (rt_pres == 1).
	u_int_32 key		inserted by encapsulator e.g. for
				authentication
				Present if (key_pres ==1 ).
	u_int_32 seq_num	Sequence number to allow for packet order
				Present if (seq_pres ==1 ).
	struct gre_sre[] routing Routing fileds (see below)
				Present if (rt_pres == 1)
 */
} __packed;

struct greip {
	struct ip gi_i;
	struct gre_h  gi_g;
} __packed;

#define gi_pr		gi_i.ip_p
#define gi_len		gi_i.ip_len
#define gi_src		gi_i.ip_src
#define gi_dst		gi_i.ip_dst
#define gi_ptype	gi_g.ptype
#define gi_flags	gi_g.flags
#define gi_options	gi_g.options

#define GRE_CP		0x8000  /* Checksum Present */
#define GRE_RP		0x4000  /* Routing Present */
#define GRE_KP		0x2000  /* Key Present */
#define GRE_SP		0x1000  /* Sequence Present */
#define GRE_SS		0x0800	/* Strict Source Route */

/*
 * CISCO uses special type for GRE tunnel created as part of WCCP
 * connection, while in fact those packets are just IPv4 encapsulated
 * into GRE.
 */
#define WCCP_PROTOCOL_TYPE	0x883E

/*
 * gre_sre defines a Source route Entry. These are needed if packets
 * should be routed over more than one tunnel hop by hop
 */
struct gre_sre {
	u_int16_t sre_family;	/* address family */
	u_char	sre_offset;	/* offset to first octet of active entry */
	u_char	sre_length;	/* number of octets in the SRE.
				   sre_lengthl==0 -> last entry. */
	u_char	*sre_rtinfo;	/* the routing information */
};

struct greioctl {
	int unit;
	struct in_addr addr;
};

/* for mobile encaps */

struct mobile_h {
	u_int16_t proto;		/* protocol and S-bit */
	u_int16_t hcrc;			/* header checksum */
	u_int32_t odst;			/* original destination address */
	u_int32_t osrc;			/* original source addr, if S-bit set */
} __packed;

struct mobip_h {
	struct ip	mi;
	struct mobile_h	mh;
} __packed;

#define MOB_H_SIZ_S		(sizeof(struct mobile_h) - sizeof(u_int32_t))
#define MOB_H_SIZ_L		(sizeof(struct mobile_h))
#define MOB_H_SBIT	0x0080

#define	GRE_TTL	30

#endif /* _KERNEL */

/*
 * ioctls needed to manipulate the interface
 */

#define GRESADDRS	_IOW('i', 101, struct ifreq)
#define GRESADDRD	_IOW('i', 102, struct ifreq)
#define GREGADDRS	_IOWR('i', 103, struct ifreq)
#define GREGADDRD	_IOWR('i', 104, struct ifreq)
#define GRESPROTO	_IOW('i' , 105, struct ifreq)
#define GREGPROTO	_IOWR('i', 106, struct ifreq)
#define GREGKEY		_IOWR('i', 107, struct ifreq)
#define GRESKEY		_IOW('i', 108, struct ifreq)

#ifdef _KERNEL
LIST_HEAD(gre_softc_head, gre_softc);
extern struct mtx gre_mtx;
extern struct gre_softc_head gre_softc_list;

u_int16_t	gre_in_cksum(u_int16_t *, u_int);
#endif /* _KERNEL */

#endif


code:
/*	$OpenBSD: if_trunk.h,v 1.11 2007/01/31 06:20:19 reyk Exp $	*/

/*
 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
 *
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/net/if_lagg.h 203548 2010-02-06 13:49:35Z eri $
 */

#ifndef _NET_LAGG_H
#define _NET_LAGG_H

/*
 * Global definitions
 */

#define	LAGG_MAX_PORTS		32	/* logically */
#define	LAGG_MAX_NAMESIZE	32	/* name of a protocol */
#define	LAGG_MAX_STACKING	4	/* maximum number of stacked laggs */

/* Port flags */
#define	LAGG_PORT_SLAVE		0x00000000	/* normal enslaved port */
#define	LAGG_PORT_MASTER	0x00000001	/* primary port */
#define	LAGG_PORT_STACK		0x00000002	/* stacked lagg port */
#define	LAGG_PORT_ACTIVE	0x00000004	/* port is active */
#define	LAGG_PORT_COLLECTING	0x00000008	/* port is receiving frames */
#define	LAGG_PORT_DISTRIBUTING	0x00000010	/* port is sending frames */
#define	LAGG_PORT_DISABLED	0x00000020	/* port is disabled */
#define	LAGG_PORT_BITS		"\20\01MASTER\02STACK\03ACTIVE\04COLLECTING" \
				  "\05DISTRIBUTING\06DISABLED"

/* Supported lagg PROTOs */
#define	LAGG_PROTO_NONE		0	/* no lagg protocol defined */
#define	LAGG_PROTO_ROUNDROBIN	1	/* simple round robin */
#define	LAGG_PROTO_FAILOVER	2	/* active failover */
#define	LAGG_PROTO_LOADBALANCE	3	/* loadbalance */
#define	LAGG_PROTO_LACP		4	/* 802.3ad lacp */
#define	LAGG_PROTO_ETHERCHANNEL	5	/* Cisco FEC */
#define	LAGG_PROTO_MAX		6

struct lagg_protos {
	const char		*lpr_name;
	int			lpr_proto;
};

#define	LAGG_PROTO_DEFAULT	LAGG_PROTO_FAILOVER
#define LAGG_PROTOS	{						\
	{ "failover",		LAGG_PROTO_FAILOVER },			\
	{ "fec",		LAGG_PROTO_ETHERCHANNEL },		\
	{ "lacp",		LAGG_PROTO_LACP },			\
	{ "loadbalance",	LAGG_PROTO_LOADBALANCE },		\
	{ "roundrobin",		LAGG_PROTO_ROUNDROBIN },		\
	{ "none",		LAGG_PROTO_NONE },			\
	{ "default",		LAGG_PROTO_DEFAULT }			\
}

/*
 * lagg ioctls.
 */

/*
 * LACP current operational parameters structure.
 */
struct lacp_opreq {
	uint16_t		actor_prio;
	uint8_t			actor_mac[ETHER_ADDR_LEN];
	uint16_t		actor_key;
	uint16_t		actor_portprio;
	uint16_t		actor_portno;
	uint8_t			actor_state;
	uint16_t		partner_prio;
	uint8_t			partner_mac[ETHER_ADDR_LEN];
	uint16_t		partner_key;
	uint16_t		partner_portprio;
	uint16_t		partner_portno;
	uint8_t			partner_state;
};

/* lagg port settings */
struct lagg_reqport {
	char			rp_ifname[IFNAMSIZ];	/* name of the lagg */
	char			rp_portname[IFNAMSIZ];	/* name of the port */
	u_int32_t		rp_prio;		/* port priority */
	u_int32_t		rp_flags;		/* port flags */
	union {
		struct lacp_opreq rpsc_lacp;
	} rp_psc;
#define rp_lacpreq	rp_psc.rpsc_lacp
};

#define	SIOCGLAGGPORT		_IOWR('i', 140, struct lagg_reqport)
#define	SIOCSLAGGPORT		 _IOW('i', 141, struct lagg_reqport)
#define	SIOCSLAGGDELPORT	 _IOW('i', 142, struct lagg_reqport)

/* lagg, ports and options */
struct lagg_reqall {
	char			ra_ifname[IFNAMSIZ];	/* name of the lagg */
	u_int			ra_proto;		/* lagg protocol */

	size_t			ra_size;		/* size of buffer */
	struct lagg_reqport	*ra_port;		/* allocated buffer */
	int			ra_ports;		/* total port count */
	union {
		struct lacp_opreq rpsc_lacp;
	} ra_psc;
#define ra_lacpreq	ra_psc.rpsc_lacp
};

#define	SIOCGLAGG		_IOWR('i', 143, struct lagg_reqall)
#define	SIOCSLAGG		 _IOW('i', 144, struct lagg_reqall)

#ifdef _KERNEL
/*
 * Internal kernel part
 */

#define	lp_ifname		lp_ifp->if_xname	/* interface name */
#define	lp_link_state		lp_ifp->if_link_state	/* link state */

#define	LAGG_PORTACTIVE(_tp)	(					\
	((_tp)->lp_link_state == LINK_STATE_UP) &&			\
	((_tp)->lp_ifp->if_flags & IFF_UP)				\
)

struct lagg_ifreq {
	union {
		struct ifreq ifreq;
		struct {
			char ifr_name[IFNAMSIZ];
			struct sockaddr_storage ifr_ss;
		} ifreq_storage;
	} ifreq;
};

#define	sc_ifflags		sc_ifp->if_flags		/* flags */
#define	sc_ifname		sc_ifp->if_xname		/* name */
#define	sc_capabilities		sc_ifp->if_capabilities	/* capabilities */

#define	IFCAP_LAGG_MASK		0xffff0000	/* private capabilities */
#define	IFCAP_LAGG_FULLDUPLEX	0x00010000	/* full duplex with >1 ports */

/* Private data used by the loadbalancing protocol */
struct lagg_lb {
	u_int32_t		lb_key;
	struct lagg_port	*lb_ports[LAGG_MAX_PORTS];
};

struct lagg_mc {
	struct ifmultiaddr      *mc_ifma;
	SLIST_ENTRY(lagg_mc)	mc_entries;
};

/* List of interfaces to have the MAC address modified */
struct lagg_llq {
	struct ifnet		*llq_ifp;
	uint8_t			llq_lladdr[ETHER_ADDR_LEN];
	SLIST_ENTRY(lagg_llq)	llq_entries;
};

struct lagg_softc {
	struct ifnet			*sc_ifp;	/* virtual interface */
	struct rwlock			sc_mtx;
	int				sc_proto;	/* lagg protocol */
	u_int				sc_count;	/* number of ports */
	struct lagg_port		*sc_primary;	/* primary port */
	struct ifmedia			sc_media;	/* media config */
	caddr_t				sc_psc;		/* protocol data */
	uint32_t			sc_seq;		/* sequence counter */

	SLIST_HEAD(__tplhd, lagg_port)	sc_ports;	/* list of interfaces */
	SLIST_ENTRY(lagg_softc)	sc_entries;

	struct task			sc_lladdr_task;
	SLIST_HEAD(__llqhd, lagg_llq)	sc_llq_head;	/* interfaces to program
							   the lladdr on */

	/* lagg protocol callbacks */
	int	(*sc_detach)(struct lagg_softc *);
	int	(*sc_start)(struct lagg_softc *, struct mbuf *);
	struct mbuf *(*sc_input)(struct lagg_softc *, struct lagg_port *,
		    struct mbuf *);
	int	(*sc_port_create)(struct lagg_port *);
	void	(*sc_port_destroy)(struct lagg_port *);
	void	(*sc_linkstate)(struct lagg_port *);
	void	(*sc_init)(struct lagg_softc *);
	void	(*sc_stop)(struct lagg_softc *);
	void	(*sc_lladdr)(struct lagg_softc *);
	void	(*sc_req)(struct lagg_softc *, caddr_t);
	void	(*sc_portreq)(struct lagg_port *, caddr_t);
#if __FreeBSD_version >= 800000
	eventhandler_tag vlan_attach;
	eventhandler_tag vlan_detach;
#endif
};

struct lagg_port {
	struct ifnet			*lp_ifp;	/* physical interface */
	struct lagg_softc		*lp_softc;	/* parent lagg */
	uint8_t				lp_lladdr[ETHER_ADDR_LEN];

	u_char				lp_iftype;	/* interface type */
	uint32_t			lp_prio;	/* port priority */
	uint32_t			lp_flags;	/* port flags */
	int				lp_ifflags;	/* saved ifp flags */
	void				*lh_cookie;	/* if state hook */
	caddr_t				lp_psc;		/* protocol data */
	int				lp_detaching;	/* ifnet is detaching */

	SLIST_HEAD(__mclhd, lagg_mc)	lp_mc_head;	/* multicast addresses */

	/* Redirected callbacks */
	int	(*lp_ioctl)(struct ifnet *, u_long, caddr_t);
	int	(*lp_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
		     struct route *);

	SLIST_ENTRY(lagg_port)		lp_entries;
};

#define	LAGG_LOCK_INIT(_sc)	rw_init(&(_sc)->sc_mtx, "if_lagg rwlock")
#define	LAGG_LOCK_DESTROY(_sc)	rw_destroy(&(_sc)->sc_mtx)
#define	LAGG_RLOCK(_sc)		rw_rlock(&(_sc)->sc_mtx)
#define	LAGG_WLOCK(_sc)		rw_wlock(&(_sc)->sc_mtx)
#define	LAGG_RUNLOCK(_sc)	rw_runlock(&(_sc)->sc_mtx)
#define	LAGG_WUNLOCK(_sc)	rw_wunlock(&(_sc)->sc_mtx)
#define	LAGG_RLOCK_ASSERT(_sc)	rw_assert(&(_sc)->sc_mtx, RA_RLOCKED)
#define	LAGG_WLOCK_ASSERT(_sc)	rw_assert(&(_sc)->sc_mtx, RA_WLOCKED)

extern struct mbuf *(*lagg_input_p)(struct ifnet *, struct mbuf *);
extern void	(*lagg_linkstate_p)(struct ifnet *, int );

int		lagg_enqueue(struct ifnet *, struct mbuf *);
uint32_t	lagg_hashmbuf(struct mbuf *, uint32_t);

#endif /* _KERNEL */

#endif /* _NET_LAGG_H */


code:
/*
 * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
 * Copyright (c) 2004-2008 Qing Li. All rights reserved.
 * Copyright (c) 2008 Kip Macy. 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 AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
 */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: release/9.0.0/sys/net/if_llatbl.h 225698 2011-09-20 20:27:26Z kmacy $");

#ifndef	_NET_IF_LLATBL_H_
#define	_NET_IF_LLATBL_H_

#include "opt_ofed.h"

#include <sys/_rwlock.h>
#include <netinet/in.h>

struct ifnet;
struct sysctl_req;
struct rt_msghdr;
struct rt_addrinfo;

struct llentry;
LIST_HEAD(llentries, llentry);

extern struct rwlock lltable_rwlock;
#define	LLTABLE_RLOCK()		rw_rlock(&lltable_rwlock)
#define	LLTABLE_RUNLOCK()	rw_runlock(&lltable_rwlock)
#define	LLTABLE_WLOCK()		rw_wlock(&lltable_rwlock)
#define	LLTABLE_WUNLOCK()	rw_wunlock(&lltable_rwlock)
#define	LLTABLE_LOCK_ASSERT()	rw_assert(&lltable_rwlock, RA_LOCKED)

/*
 * Code referencing llentry must at least hold
 * a shared lock
 */
struct llentry {
	LIST_ENTRY(llentry)	 lle_next;
	struct rwlock		 lle_lock;
	struct lltable		 *lle_tbl;
	struct llentries	 *lle_head;
	void			(*lle_free)(struct lltable *, struct llentry *);
	struct mbuf		 *la_hold;
	int     		 la_numheld;  /* # of packets currently held */
	time_t			 la_expire;
	uint16_t		 la_flags;
	uint16_t		 la_asked;
	uint16_t		 la_preempt;
	uint16_t		 ln_byhint;
	int16_t			 ln_state;	/* IPv6 has ND6_LLINFO_NOSTATE == -2 */
	uint16_t		 ln_router;
	time_t			 ln_ntick;
	int			 lle_refcnt;

	union {
		uint64_t	mac_aligned;
		uint16_t	mac16[3];
#ifdef OFED
		uint8_t		mac8[20];	/* IB needs 20 bytes. */
#endif
	} ll_addr;

	/* XXX af-private? */
	union {
		struct callout	ln_timer_ch;
		struct callout  la_timer;
	} lle_timer;
	/* NB: struct sockaddr must immediately follow */
};

#define	LLE_WLOCK(lle)		rw_wlock(&(lle)->lle_lock)
#define	LLE_RLOCK(lle)		rw_rlock(&(lle)->lle_lock)
#define	LLE_WUNLOCK(lle)	rw_wunlock(&(lle)->lle_lock)
#define	LLE_RUNLOCK(lle)	rw_runlock(&(lle)->lle_lock)
#define	LLE_DOWNGRADE(lle)	rw_downgrade(&(lle)->lle_lock)
#define	LLE_TRY_UPGRADE(lle)	rw_try_upgrade(&(lle)->lle_lock)
#define	LLE_LOCK_INIT(lle)	rw_init_flags(&(lle)->lle_lock, "lle", RW_DUPOK)
#define	LLE_LOCK_DESTROY(lle)	rw_destroy(&(lle)->lle_lock)
#define	LLE_WLOCK_ASSERT(lle)	rw_assert(&(lle)->lle_lock, RA_WLOCKED)

#define LLE_IS_VALID(lle)	(((lle) != NULL) && ((lle) != (void *)-1))

#define	LLE_ADDREF(lle) do {					\
	LLE_WLOCK_ASSERT(lle);					\
	KASSERT((lle)->lle_refcnt >= 0,				\
		("negative refcnt %d", (lle)->lle_refcnt));	\
	(lle)->lle_refcnt++;					\
} while (0)

#define	LLE_REMREF(lle)	do {					\
	LLE_WLOCK_ASSERT(lle);					\
	KASSERT((lle)->lle_refcnt > 1,				\
		("bogus refcnt %d", (lle)->lle_refcnt));	\
	(lle)->lle_refcnt--;					\
} while (0)

#define	LLE_FREE_LOCKED(lle) do {				\
	if ((lle)->lle_refcnt <= 1)				\
		(lle)->lle_tbl->llt_free((lle)->lle_tbl, (lle));\
	else {							\
		(lle)->lle_refcnt--;				\
		LLE_WUNLOCK(lle);				\
	}							\
	/* guard against invalid refs */			\
	lle = NULL;						\
} while (0)

#define	LLE_FREE(lle) do {					\
	LLE_WLOCK(lle);						\
	LLE_FREE_LOCKED(lle);					\
} while (0)

#define	ln_timer_ch	lle_timer.ln_timer_ch
#define	la_timer	lle_timer.la_timer

/* XXX bad name */
#define	L3_ADDR(lle)	((struct sockaddr *)(&lle[1]))
#define	L3_ADDR_LEN(lle)	(((struct sockaddr *)(&lle[1]))->sa_len)

#ifndef LLTBL_HASHTBL_SIZE
#define	LLTBL_HASHTBL_SIZE	32	/* default 32 ? */
#endif

#ifndef LLTBL_HASHMASK
#define	LLTBL_HASHMASK	(LLTBL_HASHTBL_SIZE - 1)
#endif

struct lltable {
	SLIST_ENTRY(lltable)	llt_link;
	struct llentries	lle_head[LLTBL_HASHTBL_SIZE];
	int			llt_af;
	struct ifnet		*llt_ifp;

	void			(*llt_free)(struct lltable *, struct llentry *);
	void			(*llt_prefix_free)(struct lltable *,
				    const struct sockaddr *prefix,
				    const struct sockaddr *mask,
				    u_int flags);
	struct llentry *	(*llt_lookup)(struct lltable *, u_int flags,
				    const struct sockaddr *l3addr);
	int			(*llt_dump)(struct lltable *,
				     struct sysctl_req *);
};
MALLOC_DECLARE(M_LLTABLE);

/*
 * flags to be passed to arplookup.
 */
#define	LLE_DELETED	0x0001	/* entry must be deleted */
#define	LLE_STATIC	0x0002	/* entry is static */
#define	LLE_IFADDR	0x0004	/* entry is interface addr */
#define	LLE_VALID	0x0008	/* ll_addr is valid */
#define	LLE_PROXY	0x0010	/* proxy entry ??? */
#define	LLE_PUB		0x0020	/* publish entry ??? */
#define	LLE_DELETE	0x4000	/* delete on a lookup - match LLE_IFADDR */
#define	LLE_CREATE	0x8000	/* create on a lookup miss */
#define	LLE_EXCLUSIVE	0x2000	/* return lle xlocked  */

#define LLATBL_HASH(key, mask) \
	(((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)

struct lltable *lltable_init(struct ifnet *, int);
void		lltable_free(struct lltable *);
void		lltable_prefix_free(int, struct sockaddr *,
                       struct sockaddr *, u_int);
#if 0
void		lltable_drain(int);
#endif
int		lltable_sysctl_dumparp(int, struct sysctl_req *);

size_t		llentry_free(struct llentry *);
int		llentry_update(struct llentry **, struct lltable *,
                       struct sockaddr_storage *, struct ifnet *);

/*
 * Generic link layer address lookup function.
 */
static __inline struct llentry *
lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
{
	return llt->llt_lookup(llt, flags, l3addr);
}

int		lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);
#endif  /* _NET_IF_LLATBL_H_ */


code:
/*	$NetBSD: if_llc.h,v 1.12 1999/11/19 20:41:19 thorpej Exp $	*/

/*-
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  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.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
 *
 *	@(#)if_llc.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: release/9.0.0/sys/net/if_llc.h 164804 2006-12-01 17:50:11Z imp $
 */

#ifndef _NET_IF_LLC_H_
#define _NET_IF_LLC_H_

/*
 * IEEE 802.2 Link Level Control headers, for use in conjunction with
 * 802.{3,4,5} media access control methods.
 *
 * Headers here do not use bit fields due to shortcommings in many
 * compilers.
 */

struct llc {
	u_int8_t llc_dsap;
	u_int8_t llc_ssap;
	union {
	    struct {
		u_int8_t control;
		u_int8_t format_id;
		u_int8_t class;
		u_int8_t window_x2;
	    } __packed type_u;
	    struct {
		u_int8_t num_snd_x2;
		u_int8_t num_rcv_x2;
	    } __packed type_i;
	    struct {
		u_int8_t control;
		u_int8_t num_rcv_x2;
	    } __packed type_s;
	    struct {
	        u_int8_t control;
		/*
		 * We cannot put the following fields in a structure because
		 * the structure rounding might cause padding.
		 */
		u_int8_t frmr_rej_pdu0;
		u_int8_t frmr_rej_pdu1;
		u_int8_t frmr_control;
		u_int8_t frmr_control_ext;
		u_int8_t frmr_cause;
	    } __packed type_frmr;
	    struct {
		u_int8_t  control;
		u_int8_t  org_code[3];
		u_int16_t ether_type;
	    } __packed type_snap;
	    struct {
		u_int8_t control;
		u_int8_t control_ext;
	    } __packed type_raw;
	} __packed llc_un;
} __packed;

struct frmrinfo {
	u_int8_t frmr_rej_pdu0;
	u_int8_t frmr_rej_pdu1;
	u_int8_t frmr_control;
	u_int8_t frmr_control_ext;
	u_int8_t frmr_cause;
} __packed;

#define	llc_control		llc_un.type_u.control
#define	llc_control_ext		llc_un.type_raw.control_ext
#define	llc_fid			llc_un.type_u.format_id
#define	llc_class		llc_un.type_u.class
#define	llc_window		llc_un.type_u.window_x2
#define	llc_frmrinfo 		llc_un.type_frmr.frmr_rej_pdu0
#define	llc_frmr_pdu0		llc_un.type_frmr.frmr_rej_pdu0
#define	llc_frmr_pdu1		llc_un.type_frmr.frmr_rej_pdu1
#define	llc_frmr_control	llc_un.type_frmr.frmr_control
#define	llc_frmr_control_ext	llc_un.type_frmr.frmr_control_ext
#define	llc_frmr_cause		llc_un.type_frmr.frmr_cause
#define	llc_snap		llc_un.type_snap

/*
 * Don't use sizeof(struct llc_un) for LLC header sizes
 */
#define LLC_ISFRAMELEN 4
#define LLC_UFRAMELEN  3
#define LLC_FRMRLEN    7
#define LLC_SNAPFRAMELEN 8

#ifdef CTASSERT
CTASSERT(sizeof (struct llc) == LLC_SNAPFRAMELEN);
#endif

/*
 * Unnumbered LLC format commands
 */
#define LLC_UI		0x3
#define LLC_UI_P	0x13
#define LLC_DISC	0x43
#define	LLC_DISC_P	0x53
#define LLC_UA		0x63
#define LLC_UA_P	0x73
#define LLC_TEST	0xe3
#define LLC_TEST_P	0xf3
#define LLC_FRMR	0x87
#define	LLC_FRMR_P	0x97
#define LLC_DM		0x0f
#define	LLC_DM_P	0x1f
#define LLC_XID		0xaf
#define LLC_XID_P	0xbf
#define LLC_SABME	0x6f
#define LLC_SABME_P	0x7f

/*
 * Supervisory LLC commands
 */
#define	LLC_RR		0x01
#define	LLC_RNR		0x05
#define	LLC_REJ		0x09

/*
 * Info format - dummy only
 */
#define	LLC_INFO	0x00

/*
 * ISO PDTR 10178 contains among others
 */
#define LLC_8021D_LSAP	0x42
#define LLC_X25_LSAP	0x7e
#define LLC_SNAP_LSAP	0xaa
#define LLC_ISO_LSAP	0xfe

#endif /* _NET_IF_LLC_H_ */