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