xref: /onnv-gate/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h (revision 10785:66ded0c3429b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52157Sdh155122  * Common Development and Distribution License (the "License").
62157Sdh155122  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
228485SPeter.Memishian@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef	INTERFACE_H
270Sstevel@tonic-gate #define	INTERFACE_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
303431Scarlsonj  * Interface.[ch] encapsulate all of the agent's knowledge of network
313431Scarlsonj  * interfaces from the DHCP agent's perspective.  See interface.c for
323431Scarlsonj  * documentation on how to use the exported functions.  Note that there are not
333431Scarlsonj  * functional interfaces for manipulating all of the fields in a PIF or LIF --
343431Scarlsonj  * please read the comments in the structure definitions below for the rules on
353431Scarlsonj  * accessing various fields.
360Sstevel@tonic-gate  */
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #ifdef	__cplusplus
390Sstevel@tonic-gate extern "C" {
400Sstevel@tonic-gate #endif
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <netinet/in.h>
430Sstevel@tonic-gate #include <net/if.h>			/* IFNAMSIZ */
440Sstevel@tonic-gate #include <sys/types.h>
450Sstevel@tonic-gate #include <netinet/dhcp.h>
460Sstevel@tonic-gate #include <dhcpagent_ipc.h>
470Sstevel@tonic-gate #include <libinetutil.h>
480Sstevel@tonic-gate 
493431Scarlsonj #include "common.h"
500Sstevel@tonic-gate #include "util.h"
510Sstevel@tonic-gate 
523431Scarlsonj #define	V4_PART_OF_V6(v6)	v6._S6_un._S6_u32[3]
530Sstevel@tonic-gate 
543431Scarlsonj struct dhcp_pif_s {
553431Scarlsonj 	dhcp_pif_t	*pif_next;	/* Note: must be first */
563431Scarlsonj 	dhcp_pif_t	*pif_prev;
573431Scarlsonj 	dhcp_lif_t	*pif_lifs;	/* pointer to logical interface list */
583431Scarlsonj 	uint32_t	pif_index;	/* interface index */
593431Scarlsonj 	uint16_t	pif_max;	/* largest DHCP packet on this if */
603431Scarlsonj 	uchar_t		*pif_hwaddr;	/* our link-layer address */
613431Scarlsonj 	uchar_t		pif_hwlen;	/* our link-layer address len */
623431Scarlsonj 	uchar_t		pif_hwtype;	/* type of link-layer */
633431Scarlsonj 	boolean_t	pif_isv6;
643431Scarlsonj 	boolean_t	pif_running;	/* interface is running */
653431Scarlsonj 	uint_t		pif_hold_count;	/* reference count */
663431Scarlsonj 	char		pif_name[LIFNAMSIZ];
678485SPeter.Memishian@Sun.COM 	char		pif_grifname[LIFNAMSIZ];
688485SPeter.Memishian@Sun.COM 	uint32_t	pif_grindex;	/* interface index for pif_grifname */
698485SPeter.Memishian@Sun.COM 	boolean_t	pif_under_ipmp;	/* is an ipmp underlying interface */
703431Scarlsonj };
710Sstevel@tonic-gate 
723431Scarlsonj struct dhcp_lif_s {
733431Scarlsonj 	dhcp_lif_t	*lif_next;	/* Note: must be first */
743431Scarlsonj 	dhcp_lif_t	*lif_prev;
753431Scarlsonj 	dhcp_pif_t	*lif_pif;	/* backpointer to parent physical if */
763431Scarlsonj 	dhcp_smach_t	*lif_smachs;	/* pointer to list of state machines */
773431Scarlsonj 	dhcp_lease_t	*lif_lease;	/* backpointer to lease holding LIF */
783431Scarlsonj 	uint64_t	lif_flags;	/* Interface flags (IFF_*) */
793431Scarlsonj 	int		lif_sock_ip_fd;	/* Bound to addr.BOOTPC for src addr */
805381Smeem 	iu_event_id_t	lif_packet_id;	/* event packet id */
813431Scarlsonj 	uint_t		lif_max;	/* maximum IP message size */
823431Scarlsonj 	uint_t		lif_hold_count;	/* reference count */
833431Scarlsonj 	boolean_t	lif_dad_wait;	/* waiting for DAD resolution */
843431Scarlsonj 	boolean_t	lif_removed;	/* removed from list */
853431Scarlsonj 	boolean_t	lif_plumbed;	/* interface plumbed by dhcpagent */
863431Scarlsonj 	boolean_t	lif_expired;	/* lease has evaporated */
873431Scarlsonj 	const char	*lif_declined;	/* reason to refuse this address */
883431Scarlsonj 	uint32_t	lif_iaid;	/* unique and stable identifier */
893431Scarlsonj 	iu_event_id_t	lif_iaid_id;	/* for delayed writes to /etc */
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	/*
923431Scarlsonj 	 * While in any states except ADOPTING, INIT, INFORMATION and
933431Scarlsonj 	 * INFORM_SENT, the following three fields are equal to what we believe
943431Scarlsonj 	 * the current address, netmask, and broadcast address on the interface
953431Scarlsonj 	 * to be.  This is so we can detect if the user changes them and
963431Scarlsonj 	 * abandon the interface.
970Sstevel@tonic-gate 	 */
980Sstevel@tonic-gate 
993431Scarlsonj 	in6_addr_t	lif_v6addr;	/* our IP address */
1003431Scarlsonj 	in6_addr_t	lif_v6mask;	/* our netmask */
1013431Scarlsonj 	in6_addr_t	lif_v6peer;	/* our broadcast or peer address */
1020Sstevel@tonic-gate 
1033431Scarlsonj 	dhcp_timer_t	lif_preferred;	/* lease preferred timer (v6 only) */
1043431Scarlsonj 	dhcp_timer_t	lif_expire;	/* lease expire timer */
1050Sstevel@tonic-gate 
1063431Scarlsonj 	char		lif_name[LIFNAMSIZ];
1073431Scarlsonj };
1083431Scarlsonj #define	lif_addr	V4_PART_OF_V6(lif_v6addr)
1093431Scarlsonj #define	lif_netmask	V4_PART_OF_V6(lif_v6mask)
1103431Scarlsonj #define	lif_peer	V4_PART_OF_V6(lif_v6peer)
1113431Scarlsonj #define	lif_broadcast	V4_PART_OF_V6(lif_v6peer)
1120Sstevel@tonic-gate 
1133431Scarlsonj /* used by expired_lif_state to express state of DHCP interfaces */
1143431Scarlsonj typedef enum dhcp_expire_e {
1153431Scarlsonj 	DHCP_EXP_NOLIFS,
1163431Scarlsonj 	DHCP_EXP_NOEXP,
1173431Scarlsonj 	DHCP_EXP_ALLEXP,
1183431Scarlsonj 	DHCP_EXP_SOMEEXP
1193431Scarlsonj } dhcp_expire_t;
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate /*
1223431Scarlsonj  * A word on memory management and LIFs and PIFs:
1230Sstevel@tonic-gate  *
1243431Scarlsonj  * Since LIFs are often passed as context to callback functions, they cannot be
1253431Scarlsonj  * freed when the interface they represent is dropped or released (or when
1263431Scarlsonj  * those callbacks finally go off, they will be hosed).  To handle this
1273431Scarlsonj  * situation, the structures are reference counted.  Here are the rules for
1283431Scarlsonj  * managing these counts:
1290Sstevel@tonic-gate  *
1303431Scarlsonj  * A PIF is created through insert_pif().  Along with initializing the PIF,
1313431Scarlsonj  * this puts a hold on the PIF.  A LIF is created through insert_lif().  This
1323431Scarlsonj  * also initializes the LIF and places a hold on it.  The caller's hold on the
1333431Scarlsonj  * underlying PIF is transferred to the LIF.
1340Sstevel@tonic-gate  *
1353431Scarlsonj  * Whenever a lease is released or dropped (implicitly or explicitly),
1363431Scarlsonj  * remove_lif() is called, which sets the lif_removed flag and removes the
1373431Scarlsonj  * interface from the internal list of managed interfaces.  Lastly,
1383431Scarlsonj  * remove_lif() calls release_lif() to remove the hold acquired in
1393431Scarlsonj  * insert_lif().  If this decrements the hold count on the interface to zero,
1403431Scarlsonj  * then free() is called and the hold on the PIF is dropped.  If there are
1413431Scarlsonj  * holds other than the hold acquired in insert_lif(), the hold count will
1423431Scarlsonj  * still be > 0, and the interface will remain allocated (though dormant).
1430Sstevel@tonic-gate  *
1443431Scarlsonj  * Whenever a callback is scheduled against a LIF, another hold must be put on
1453431Scarlsonj  * the ifslist through hold_lif().
1460Sstevel@tonic-gate  *
1473431Scarlsonj  * Whenever a callback is called back against a LIF, release_lif() must be
1483431Scarlsonj  * called to decrement the hold count, which may end up freeing the LIF if the
1493431Scarlsonj  * hold count becomes zero.
1500Sstevel@tonic-gate  *
1513431Scarlsonj  * Since some callbacks may take a long time to get called back (such as
1523431Scarlsonj  * timeout callbacks for lease expiration, etc), it is sometimes more
1533431Scarlsonj  * appropriate to cancel the callbacks and call release_lif() if the
1543431Scarlsonj  * cancellation succeeds.  This is done in remove_lif() for the lease preferred
1553431Scarlsonj  * and expire callbacks.
1563431Scarlsonj  *
1573431Scarlsonj  * In general, a callback may also call verify_lif() when it gets called back
1583431Scarlsonj  * in addition to release_lif(), to make sure that the interface is still in
1593431Scarlsonj  * fact under the dhcpagent's control.  To make coding simpler, there is a
1603431Scarlsonj  * third function, verify_smach(), which performs both the release_lif() and
1613431Scarlsonj  * the verify_lif() on all LIFs controlled by a state machine.
1620Sstevel@tonic-gate  */
1630Sstevel@tonic-gate 
1643431Scarlsonj extern dhcp_pif_t *v4root;
1653431Scarlsonj extern dhcp_pif_t *v6root;
1663431Scarlsonj 
1673431Scarlsonj dhcp_pif_t	*insert_pif(const char *, boolean_t, int *);
1683431Scarlsonj void		hold_pif(dhcp_pif_t *);
1693431Scarlsonj void		release_pif(dhcp_pif_t *);
1703431Scarlsonj dhcp_pif_t	*lookup_pif_by_uindex(uint16_t, dhcp_pif_t *, boolean_t);
1713431Scarlsonj dhcp_pif_t	*lookup_pif_by_name(const char *, boolean_t);
1723431Scarlsonj void		pif_status(dhcp_pif_t *, boolean_t);
1733431Scarlsonj 
1743431Scarlsonj dhcp_lif_t	*insert_lif(dhcp_pif_t *, const char *, int *);
1753431Scarlsonj void		hold_lif(dhcp_lif_t *);
1763431Scarlsonj void		release_lif(dhcp_lif_t *);
1773431Scarlsonj void		remove_lif(dhcp_lif_t *);
1783431Scarlsonj dhcp_lif_t	*lookup_lif_by_name(const char *, const dhcp_pif_t *);
1793431Scarlsonj boolean_t	verify_lif(const dhcp_lif_t *);
1803431Scarlsonj dhcp_lif_t	*plumb_lif(dhcp_pif_t *, const in6_addr_t *);
1813431Scarlsonj void		unplumb_lif(dhcp_lif_t *);
1823431Scarlsonj dhcp_lif_t	*attach_lif(const char *, boolean_t, int *);
183*10785SPeter.Memishian@Sun.COM int		set_lif_dhcp(dhcp_lif_t *);
1843431Scarlsonj void		set_lif_deprecated(dhcp_lif_t *);
1853431Scarlsonj boolean_t	clear_lif_deprecated(dhcp_lif_t *);
1868485SPeter.Memishian@Sun.COM boolean_t	open_ip_lif(dhcp_lif_t *, in_addr_t, boolean_t);
1873431Scarlsonj void		close_ip_lif(dhcp_lif_t *);
1883431Scarlsonj void		lif_mark_decline(dhcp_lif_t *, const char *);
1893431Scarlsonj boolean_t	schedule_lif_timer(dhcp_lif_t *, dhcp_timer_t *,
1900Sstevel@tonic-gate 		    iu_tq_callback_t *);
1913431Scarlsonj void		cancel_lif_timers(dhcp_lif_t *);
1923431Scarlsonj dhcp_expire_t	expired_lif_state(dhcp_smach_t *);
1933431Scarlsonj dhcp_lif_t	*find_expired_lif(dhcp_smach_t *);
1943431Scarlsonj 
1953431Scarlsonj uint_t		get_max_mtu(boolean_t);
1963431Scarlsonj void		remove_v6_strays(void);
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate #ifdef	__cplusplus
1990Sstevel@tonic-gate }
2000Sstevel@tonic-gate #endif
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate #endif	/* INTERFACE_H */
203