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