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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
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.
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>
52 #define V4_PART_OF_V6(v6) v6._S6_un._S6_u32[3]
55 dhcp_pif_t
*pif_next
; /* Note: must be first */
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 */
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 */
73 dhcp_lif_t
*lif_next
; /* Note: must be first */
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 */
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.
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 */
103 dhcp_timer_t lif_preferred
; /* lease preferred timer (v6 only) */
104 dhcp_timer_t lif_expire
; /* lease expire timer */
106 char lif_name
[LIFNAMSIZ
];
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)
113 /* used by expired_lif_state to express state of DHCP interfaces */
114 typedef enum dhcp_expire_e
{
122 * A word on memory management and LIFs and PIFs:
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:
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.
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).
144 * Whenever a callback is scheduled against a LIF, another hold must be put on
145 * the ifslist through hold_lif().
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.
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.
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.
164 extern dhcp_pif_t
*v4root
;
165 extern dhcp_pif_t
*v6root
;
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
);
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
*,
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
*);
195 uint_t
get_max_mtu(boolean_t
);
196 void remove_v6_strays(void);
202 #endif /* INTERFACE_H */