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