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