xref: /titanic_50/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h (revision dc918d99d74acfa24794f5fa3796e4f4c88eac23)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5c2934490Sdh155122  * Common Development and Distribution License (the "License").
6c2934490Sdh155122  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22e11c3f44Smeem  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	INTERFACE_H
277c478bd9Sstevel@tonic-gate #define	INTERFACE_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
30d04ccbb3Scarlsonj  * Interface.[ch] encapsulate all of the agent's knowledge of network
31d04ccbb3Scarlsonj  * interfaces from the DHCP agent's perspective.  See interface.c for
32d04ccbb3Scarlsonj  * documentation on how to use the exported functions.  Note that there are not
33d04ccbb3Scarlsonj  * functional interfaces for manipulating all of the fields in a PIF or LIF --
34d04ccbb3Scarlsonj  * please read the comments in the structure definitions below for the rules on
35d04ccbb3Scarlsonj  * accessing various fields.
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
397c478bd9Sstevel@tonic-gate extern "C" {
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include <netinet/in.h>
437c478bd9Sstevel@tonic-gate #include <net/if.h>			/* IFNAMSIZ */
447c478bd9Sstevel@tonic-gate #include <sys/types.h>
457c478bd9Sstevel@tonic-gate #include <netinet/dhcp.h>
467c478bd9Sstevel@tonic-gate #include <dhcpagent_ipc.h>
477c478bd9Sstevel@tonic-gate #include <libinetutil.h>
487c478bd9Sstevel@tonic-gate 
49d04ccbb3Scarlsonj #include "common.h"
507c478bd9Sstevel@tonic-gate #include "util.h"
517c478bd9Sstevel@tonic-gate 
52d04ccbb3Scarlsonj #define	V4_PART_OF_V6(v6)	v6._S6_un._S6_u32[3]
537c478bd9Sstevel@tonic-gate 
54d04ccbb3Scarlsonj struct dhcp_pif_s {
55d04ccbb3Scarlsonj 	dhcp_pif_t	*pif_next;	/* Note: must be first */
56d04ccbb3Scarlsonj 	dhcp_pif_t	*pif_prev;
57d04ccbb3Scarlsonj 	dhcp_lif_t	*pif_lifs;	/* pointer to logical interface list */
58d04ccbb3Scarlsonj 	uint32_t	pif_index;	/* interface index */
59d04ccbb3Scarlsonj 	uint16_t	pif_max;	/* largest DHCP packet on this if */
60d04ccbb3Scarlsonj 	uchar_t		*pif_hwaddr;	/* our link-layer address */
61d04ccbb3Scarlsonj 	uchar_t		pif_hwlen;	/* our link-layer address len */
62d04ccbb3Scarlsonj 	uchar_t		pif_hwtype;	/* type of link-layer */
63d04ccbb3Scarlsonj 	boolean_t	pif_isv6;
64d04ccbb3Scarlsonj 	boolean_t	pif_running;	/* interface is running */
65d04ccbb3Scarlsonj 	uint_t		pif_hold_count;	/* reference count */
66d04ccbb3Scarlsonj 	char		pif_name[LIFNAMSIZ];
67e11c3f44Smeem 	char		pif_grifname[LIFNAMSIZ];
68e11c3f44Smeem 	uint32_t	pif_grindex;	/* interface index for pif_grifname */
69e11c3f44Smeem 	boolean_t	pif_under_ipmp;	/* is an ipmp underlying interface */
707c478bd9Sstevel@tonic-gate };
717c478bd9Sstevel@tonic-gate 
72d04ccbb3Scarlsonj struct dhcp_lif_s {
73d04ccbb3Scarlsonj 	dhcp_lif_t	*lif_next;	/* Note: must be first */
74d04ccbb3Scarlsonj 	dhcp_lif_t	*lif_prev;
75d04ccbb3Scarlsonj 	dhcp_pif_t	*lif_pif;	/* backpointer to parent physical if */
76d04ccbb3Scarlsonj 	dhcp_smach_t	*lif_smachs;	/* pointer to list of state machines */
77d04ccbb3Scarlsonj 	dhcp_lease_t	*lif_lease;	/* backpointer to lease holding LIF */
78d04ccbb3Scarlsonj 	uint64_t	lif_flags;	/* Interface flags (IFF_*) */
79d04ccbb3Scarlsonj 	int		lif_sock_ip_fd;	/* Bound to addr.BOOTPC for src addr */
80e704a8f2Smeem 	iu_event_id_t	lif_packet_id;	/* event packet id */
81d04ccbb3Scarlsonj 	uint_t		lif_max;	/* maximum IP message size */
82d04ccbb3Scarlsonj 	uint_t		lif_hold_count;	/* reference count */
83d04ccbb3Scarlsonj 	boolean_t	lif_dad_wait;	/* waiting for DAD resolution */
84d04ccbb3Scarlsonj 	boolean_t	lif_removed;	/* removed from list */
85d04ccbb3Scarlsonj 	boolean_t	lif_plumbed;	/* interface plumbed by dhcpagent */
86d04ccbb3Scarlsonj 	boolean_t	lif_expired;	/* lease has evaporated */
87d04ccbb3Scarlsonj 	const char	*lif_declined;	/* reason to refuse this address */
88d04ccbb3Scarlsonj 	uint32_t	lif_iaid;	/* unique and stable identifier */
89d04ccbb3Scarlsonj 	iu_event_id_t	lif_iaid_id;	/* for delayed writes to /etc */
90d04ccbb3Scarlsonj 
917c478bd9Sstevel@tonic-gate 	/*
92d04ccbb3Scarlsonj 	 * While in any states except ADOPTING, INIT, INFORMATION and
93d04ccbb3Scarlsonj 	 * INFORM_SENT, the following three fields are equal to what we believe
94d04ccbb3Scarlsonj 	 * the current address, netmask, and broadcast address on the interface
95d04ccbb3Scarlsonj 	 * to be.  This is so we can detect if the user changes them and
96d04ccbb3Scarlsonj 	 * abandon the interface.
977c478bd9Sstevel@tonic-gate 	 */
987c478bd9Sstevel@tonic-gate 
99d04ccbb3Scarlsonj 	in6_addr_t	lif_v6addr;	/* our IP address */
100d04ccbb3Scarlsonj 	in6_addr_t	lif_v6mask;	/* our netmask */
101d04ccbb3Scarlsonj 	in6_addr_t	lif_v6peer;	/* our broadcast or peer address */
102d04ccbb3Scarlsonj 
103d04ccbb3Scarlsonj 	dhcp_timer_t	lif_preferred;	/* lease preferred timer (v6 only) */
104d04ccbb3Scarlsonj 	dhcp_timer_t	lif_expire;	/* lease expire timer */
105d04ccbb3Scarlsonj 
106d04ccbb3Scarlsonj 	char		lif_name[LIFNAMSIZ];
107d04ccbb3Scarlsonj };
108d04ccbb3Scarlsonj #define	lif_addr	V4_PART_OF_V6(lif_v6addr)
109d04ccbb3Scarlsonj #define	lif_netmask	V4_PART_OF_V6(lif_v6mask)
110d04ccbb3Scarlsonj #define	lif_peer	V4_PART_OF_V6(lif_v6peer)
111d04ccbb3Scarlsonj #define	lif_broadcast	V4_PART_OF_V6(lif_v6peer)
112d04ccbb3Scarlsonj 
113d04ccbb3Scarlsonj /* used by expired_lif_state to express state of DHCP interfaces */
114d04ccbb3Scarlsonj typedef enum dhcp_expire_e {
115d04ccbb3Scarlsonj 	DHCP_EXP_NOLIFS,
116d04ccbb3Scarlsonj 	DHCP_EXP_NOEXP,
117d04ccbb3Scarlsonj 	DHCP_EXP_ALLEXP,
118d04ccbb3Scarlsonj 	DHCP_EXP_SOMEEXP
119d04ccbb3Scarlsonj } dhcp_expire_t;
120d04ccbb3Scarlsonj 
121d04ccbb3Scarlsonj /*
122d04ccbb3Scarlsonj  * A word on memory management and LIFs and PIFs:
123d04ccbb3Scarlsonj  *
124d04ccbb3Scarlsonj  * Since LIFs are often passed as context to callback functions, they cannot be
125d04ccbb3Scarlsonj  * freed when the interface they represent is dropped or released (or when
126d04ccbb3Scarlsonj  * those callbacks finally go off, they will be hosed).  To handle this
127d04ccbb3Scarlsonj  * situation, the structures are reference counted.  Here are the rules for
128d04ccbb3Scarlsonj  * managing these counts:
129d04ccbb3Scarlsonj  *
130d04ccbb3Scarlsonj  * A PIF is created through insert_pif().  Along with initializing the PIF,
131d04ccbb3Scarlsonj  * this puts a hold on the PIF.  A LIF is created through insert_lif().  This
132d04ccbb3Scarlsonj  * also initializes the LIF and places a hold on it.  The caller's hold on the
133d04ccbb3Scarlsonj  * underlying PIF is transferred to the LIF.
134d04ccbb3Scarlsonj  *
135d04ccbb3Scarlsonj  * Whenever a lease is released or dropped (implicitly or explicitly),
136d04ccbb3Scarlsonj  * remove_lif() is called, which sets the lif_removed flag and removes the
137d04ccbb3Scarlsonj  * interface from the internal list of managed interfaces.  Lastly,
138d04ccbb3Scarlsonj  * remove_lif() calls release_lif() to remove the hold acquired in
139d04ccbb3Scarlsonj  * insert_lif().  If this decrements the hold count on the interface to zero,
140d04ccbb3Scarlsonj  * then free() is called and the hold on the PIF is dropped.  If there are
141d04ccbb3Scarlsonj  * holds other than the hold acquired in insert_lif(), the hold count will
142d04ccbb3Scarlsonj  * still be > 0, and the interface will remain allocated (though dormant).
143d04ccbb3Scarlsonj  *
144d04ccbb3Scarlsonj  * Whenever a callback is scheduled against a LIF, another hold must be put on
145d04ccbb3Scarlsonj  * the ifslist through hold_lif().
146d04ccbb3Scarlsonj  *
147d04ccbb3Scarlsonj  * Whenever a callback is called back against a LIF, release_lif() must be
148d04ccbb3Scarlsonj  * called to decrement the hold count, which may end up freeing the LIF if the
149d04ccbb3Scarlsonj  * hold count becomes zero.
150d04ccbb3Scarlsonj  *
151d04ccbb3Scarlsonj  * Since some callbacks may take a long time to get called back (such as
152d04ccbb3Scarlsonj  * timeout callbacks for lease expiration, etc), it is sometimes more
153d04ccbb3Scarlsonj  * appropriate to cancel the callbacks and call release_lif() if the
154d04ccbb3Scarlsonj  * cancellation succeeds.  This is done in remove_lif() for the lease preferred
155d04ccbb3Scarlsonj  * and expire callbacks.
156d04ccbb3Scarlsonj  *
157d04ccbb3Scarlsonj  * In general, a callback may also call verify_lif() when it gets called back
158d04ccbb3Scarlsonj  * in addition to release_lif(), to make sure that the interface is still in
159d04ccbb3Scarlsonj  * fact under the dhcpagent's control.  To make coding simpler, there is a
160d04ccbb3Scarlsonj  * third function, verify_smach(), which performs both the release_lif() and
161d04ccbb3Scarlsonj  * the verify_lif() on all LIFs controlled by a state machine.
162d04ccbb3Scarlsonj  */
163d04ccbb3Scarlsonj 
164d04ccbb3Scarlsonj extern dhcp_pif_t *v4root;
165d04ccbb3Scarlsonj extern dhcp_pif_t *v6root;
166d04ccbb3Scarlsonj 
167d04ccbb3Scarlsonj dhcp_pif_t	*insert_pif(const char *, boolean_t, int *);
168d04ccbb3Scarlsonj void		hold_pif(dhcp_pif_t *);
169d04ccbb3Scarlsonj void		release_pif(dhcp_pif_t *);
170d04ccbb3Scarlsonj dhcp_pif_t	*lookup_pif_by_uindex(uint16_t, dhcp_pif_t *, boolean_t);
171d04ccbb3Scarlsonj dhcp_pif_t	*lookup_pif_by_name(const char *, boolean_t);
172d04ccbb3Scarlsonj void		pif_status(dhcp_pif_t *, boolean_t);
173d04ccbb3Scarlsonj 
174d04ccbb3Scarlsonj dhcp_lif_t	*insert_lif(dhcp_pif_t *, const char *, int *);
175d04ccbb3Scarlsonj void		hold_lif(dhcp_lif_t *);
176d04ccbb3Scarlsonj void		release_lif(dhcp_lif_t *);
177d04ccbb3Scarlsonj void		remove_lif(dhcp_lif_t *);
178d04ccbb3Scarlsonj dhcp_lif_t	*lookup_lif_by_name(const char *, const dhcp_pif_t *);
179d04ccbb3Scarlsonj boolean_t	verify_lif(const dhcp_lif_t *);
180d04ccbb3Scarlsonj dhcp_lif_t	*plumb_lif(dhcp_pif_t *, const in6_addr_t *);
181d04ccbb3Scarlsonj void		unplumb_lif(dhcp_lif_t *);
182d04ccbb3Scarlsonj dhcp_lif_t	*attach_lif(const char *, boolean_t, int *);
183*dc918d99Smeem int		set_lif_dhcp(dhcp_lif_t *);
184d04ccbb3Scarlsonj void		set_lif_deprecated(dhcp_lif_t *);
185d04ccbb3Scarlsonj boolean_t	clear_lif_deprecated(dhcp_lif_t *);
186e11c3f44Smeem boolean_t	open_ip_lif(dhcp_lif_t *, in_addr_t, boolean_t);
187d04ccbb3Scarlsonj void		close_ip_lif(dhcp_lif_t *);
188d04ccbb3Scarlsonj void		lif_mark_decline(dhcp_lif_t *, const char *);
189d04ccbb3Scarlsonj boolean_t	schedule_lif_timer(dhcp_lif_t *, dhcp_timer_t *,
1907c478bd9Sstevel@tonic-gate 		    iu_tq_callback_t *);
191d04ccbb3Scarlsonj void		cancel_lif_timers(dhcp_lif_t *);
192d04ccbb3Scarlsonj dhcp_expire_t	expired_lif_state(dhcp_smach_t *);
193d04ccbb3Scarlsonj dhcp_lif_t	*find_expired_lif(dhcp_smach_t *);
194d04ccbb3Scarlsonj 
195d04ccbb3Scarlsonj uint_t		get_max_mtu(boolean_t);
196d04ccbb3Scarlsonj void		remove_v6_strays(void);
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate #endif
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate #endif	/* INTERFACE_H */
203