10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 52157Sdh155122 * Common Development and Distribution License (the "License"). 62157Sdh155122 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*3431Scarlsonj * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef INTERFACE_H 270Sstevel@tonic-gate #define INTERFACE_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate /* 32*3431Scarlsonj * Interface.[ch] encapsulate all of the agent's knowledge of network 33*3431Scarlsonj * interfaces from the DHCP agent's perspective. See interface.c for 34*3431Scarlsonj * documentation on how to use the exported functions. Note that there are not 35*3431Scarlsonj * functional interfaces for manipulating all of the fields in a PIF or LIF -- 36*3431Scarlsonj * please read the comments in the structure definitions below for the rules on 37*3431Scarlsonj * accessing various fields. 380Sstevel@tonic-gate */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate #ifdef __cplusplus 410Sstevel@tonic-gate extern "C" { 420Sstevel@tonic-gate #endif 430Sstevel@tonic-gate 440Sstevel@tonic-gate #include <netinet/in.h> 450Sstevel@tonic-gate #include <net/if.h> /* IFNAMSIZ */ 460Sstevel@tonic-gate #include <sys/types.h> 470Sstevel@tonic-gate #include <netinet/dhcp.h> 480Sstevel@tonic-gate #include <dhcpagent_ipc.h> 490Sstevel@tonic-gate #include <libinetutil.h> 500Sstevel@tonic-gate 51*3431Scarlsonj #include "common.h" 520Sstevel@tonic-gate #include "util.h" 530Sstevel@tonic-gate 54*3431Scarlsonj #define V4_PART_OF_V6(v6) v6._S6_un._S6_u32[3] 550Sstevel@tonic-gate 56*3431Scarlsonj struct dhcp_pif_s { 57*3431Scarlsonj dhcp_pif_t *pif_next; /* Note: must be first */ 58*3431Scarlsonj dhcp_pif_t *pif_prev; 59*3431Scarlsonj dhcp_lif_t *pif_lifs; /* pointer to logical interface list */ 60*3431Scarlsonj uint32_t pif_index; /* interface index */ 61*3431Scarlsonj uint16_t pif_max; /* largest DHCP packet on this if */ 62*3431Scarlsonj uchar_t *pif_hwaddr; /* our link-layer address */ 63*3431Scarlsonj uchar_t pif_hwlen; /* our link-layer address len */ 64*3431Scarlsonj uchar_t pif_hwtype; /* type of link-layer */ 65*3431Scarlsonj boolean_t pif_isv6; 66*3431Scarlsonj boolean_t pif_running; /* interface is running */ 67*3431Scarlsonj int pif_dlpi_fd; 68*3431Scarlsonj int pif_dlpi_count; 69*3431Scarlsonj iu_event_id_t pif_dlpi_id; /* event id for ack/nak/offer */ 70*3431Scarlsonj uint_t pif_hold_count; /* reference count */ 710Sstevel@tonic-gate 720Sstevel@tonic-gate /* 73*3431Scarlsonj * The destination address is the broadcast address of the interface, 74*3431Scarlsonj * in DLPI terms (which means it includes both a link-layer broadcast 75*3431Scarlsonj * address and a SAP, and the order depends on the requirements of the 76*3431Scarlsonj * underlying driver). We store it as a token like this because it's 77*3431Scarlsonj * generally how we need to use it. 780Sstevel@tonic-gate */ 790Sstevel@tonic-gate 80*3431Scarlsonj uchar_t *pif_daddr; /* our destination address */ 81*3431Scarlsonj uchar_t pif_dlen; /* our destination address len */ 820Sstevel@tonic-gate 83*3431Scarlsonj uint_t pif_saplen; /* the SAP len */ 84*3431Scarlsonj boolean_t pif_sap_before; /* does SAP come before address? */ 85*3431Scarlsonj char pif_name[LIFNAMSIZ]; 86*3431Scarlsonj }; 870Sstevel@tonic-gate 88*3431Scarlsonj struct dhcp_lif_s { 89*3431Scarlsonj dhcp_lif_t *lif_next; /* Note: must be first */ 90*3431Scarlsonj dhcp_lif_t *lif_prev; 91*3431Scarlsonj dhcp_pif_t *lif_pif; /* backpointer to parent physical if */ 92*3431Scarlsonj dhcp_smach_t *lif_smachs; /* pointer to list of state machines */ 93*3431Scarlsonj dhcp_lease_t *lif_lease; /* backpointer to lease holding LIF */ 94*3431Scarlsonj uint64_t lif_flags; /* Interface flags (IFF_*) */ 95*3431Scarlsonj int lif_sock_ip_fd; /* Bound to addr.BOOTPC for src addr */ 96*3431Scarlsonj iu_event_id_t lif_acknak_id; /* event acknak id */ 97*3431Scarlsonj uint_t lif_max; /* maximum IP message size */ 98*3431Scarlsonj uint_t lif_hold_count; /* reference count */ 99*3431Scarlsonj boolean_t lif_dad_wait; /* waiting for DAD resolution */ 100*3431Scarlsonj boolean_t lif_removed; /* removed from list */ 101*3431Scarlsonj boolean_t lif_plumbed; /* interface plumbed by dhcpagent */ 102*3431Scarlsonj boolean_t lif_expired; /* lease has evaporated */ 103*3431Scarlsonj const char *lif_declined; /* reason to refuse this address */ 104*3431Scarlsonj uint32_t lif_iaid; /* unique and stable identifier */ 105*3431Scarlsonj iu_event_id_t lif_iaid_id; /* for delayed writes to /etc */ 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate /* 108*3431Scarlsonj * While in any states except ADOPTING, INIT, INFORMATION and 109*3431Scarlsonj * INFORM_SENT, the following three fields are equal to what we believe 110*3431Scarlsonj * the current address, netmask, and broadcast address on the interface 111*3431Scarlsonj * to be. This is so we can detect if the user changes them and 112*3431Scarlsonj * abandon the interface. 1130Sstevel@tonic-gate */ 1140Sstevel@tonic-gate 115*3431Scarlsonj in6_addr_t lif_v6addr; /* our IP address */ 116*3431Scarlsonj in6_addr_t lif_v6mask; /* our netmask */ 117*3431Scarlsonj in6_addr_t lif_v6peer; /* our broadcast or peer address */ 1180Sstevel@tonic-gate 119*3431Scarlsonj dhcp_timer_t lif_preferred; /* lease preferred timer (v6 only) */ 120*3431Scarlsonj dhcp_timer_t lif_expire; /* lease expire timer */ 1210Sstevel@tonic-gate 122*3431Scarlsonj char lif_name[LIFNAMSIZ]; 123*3431Scarlsonj }; 124*3431Scarlsonj #define lif_addr V4_PART_OF_V6(lif_v6addr) 125*3431Scarlsonj #define lif_netmask V4_PART_OF_V6(lif_v6mask) 126*3431Scarlsonj #define lif_peer V4_PART_OF_V6(lif_v6peer) 127*3431Scarlsonj #define lif_broadcast V4_PART_OF_V6(lif_v6peer) 1280Sstevel@tonic-gate 129*3431Scarlsonj /* used by expired_lif_state to express state of DHCP interfaces */ 130*3431Scarlsonj typedef enum dhcp_expire_e { 131*3431Scarlsonj DHCP_EXP_NOLIFS, 132*3431Scarlsonj DHCP_EXP_NOEXP, 133*3431Scarlsonj DHCP_EXP_ALLEXP, 134*3431Scarlsonj DHCP_EXP_SOMEEXP 135*3431Scarlsonj } dhcp_expire_t; 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate /* 138*3431Scarlsonj * A word on memory management and LIFs and PIFs: 1390Sstevel@tonic-gate * 140*3431Scarlsonj * Since LIFs are often passed as context to callback functions, they cannot be 141*3431Scarlsonj * freed when the interface they represent is dropped or released (or when 142*3431Scarlsonj * those callbacks finally go off, they will be hosed). To handle this 143*3431Scarlsonj * situation, the structures are reference counted. Here are the rules for 144*3431Scarlsonj * managing these counts: 1450Sstevel@tonic-gate * 146*3431Scarlsonj * A PIF is created through insert_pif(). Along with initializing the PIF, 147*3431Scarlsonj * this puts a hold on the PIF. A LIF is created through insert_lif(). This 148*3431Scarlsonj * also initializes the LIF and places a hold on it. The caller's hold on the 149*3431Scarlsonj * underlying PIF is transferred to the LIF. 1500Sstevel@tonic-gate * 151*3431Scarlsonj * Whenever a lease is released or dropped (implicitly or explicitly), 152*3431Scarlsonj * remove_lif() is called, which sets the lif_removed flag and removes the 153*3431Scarlsonj * interface from the internal list of managed interfaces. Lastly, 154*3431Scarlsonj * remove_lif() calls release_lif() to remove the hold acquired in 155*3431Scarlsonj * insert_lif(). If this decrements the hold count on the interface to zero, 156*3431Scarlsonj * then free() is called and the hold on the PIF is dropped. If there are 157*3431Scarlsonj * holds other than the hold acquired in insert_lif(), the hold count will 158*3431Scarlsonj * still be > 0, and the interface will remain allocated (though dormant). 1590Sstevel@tonic-gate * 160*3431Scarlsonj * Whenever a callback is scheduled against a LIF, another hold must be put on 161*3431Scarlsonj * the ifslist through hold_lif(). 1620Sstevel@tonic-gate * 163*3431Scarlsonj * Whenever a callback is called back against a LIF, release_lif() must be 164*3431Scarlsonj * called to decrement the hold count, which may end up freeing the LIF if the 165*3431Scarlsonj * hold count becomes zero. 1660Sstevel@tonic-gate * 167*3431Scarlsonj * Since some callbacks may take a long time to get called back (such as 168*3431Scarlsonj * timeout callbacks for lease expiration, etc), it is sometimes more 169*3431Scarlsonj * appropriate to cancel the callbacks and call release_lif() if the 170*3431Scarlsonj * cancellation succeeds. This is done in remove_lif() for the lease preferred 171*3431Scarlsonj * and expire callbacks. 172*3431Scarlsonj * 173*3431Scarlsonj * In general, a callback may also call verify_lif() when it gets called back 174*3431Scarlsonj * in addition to release_lif(), to make sure that the interface is still in 175*3431Scarlsonj * fact under the dhcpagent's control. To make coding simpler, there is a 176*3431Scarlsonj * third function, verify_smach(), which performs both the release_lif() and 177*3431Scarlsonj * the verify_lif() on all LIFs controlled by a state machine. 1780Sstevel@tonic-gate */ 1790Sstevel@tonic-gate 180*3431Scarlsonj extern dhcp_pif_t *v4root; 181*3431Scarlsonj extern dhcp_pif_t *v6root; 182*3431Scarlsonj 183*3431Scarlsonj dhcp_pif_t *insert_pif(const char *, boolean_t, int *); 184*3431Scarlsonj void hold_pif(dhcp_pif_t *); 185*3431Scarlsonj void release_pif(dhcp_pif_t *); 186*3431Scarlsonj dhcp_pif_t *lookup_pif_by_index(uint_t, boolean_t); 187*3431Scarlsonj dhcp_pif_t *lookup_pif_by_uindex(uint16_t, dhcp_pif_t *, boolean_t); 188*3431Scarlsonj dhcp_pif_t *lookup_pif_by_name(const char *, boolean_t); 189*3431Scarlsonj boolean_t open_dlpi_pif(dhcp_pif_t *); 190*3431Scarlsonj void close_dlpi_pif(dhcp_pif_t *); 191*3431Scarlsonj void pif_status(dhcp_pif_t *, boolean_t); 192*3431Scarlsonj 193*3431Scarlsonj dhcp_lif_t *insert_lif(dhcp_pif_t *, const char *, int *); 194*3431Scarlsonj void hold_lif(dhcp_lif_t *); 195*3431Scarlsonj void release_lif(dhcp_lif_t *); 196*3431Scarlsonj void remove_lif(dhcp_lif_t *); 197*3431Scarlsonj dhcp_lif_t *lookup_lif_by_name(const char *, const dhcp_pif_t *); 198*3431Scarlsonj boolean_t verify_lif(const dhcp_lif_t *); 199*3431Scarlsonj dhcp_lif_t *plumb_lif(dhcp_pif_t *, const in6_addr_t *); 200*3431Scarlsonj void unplumb_lif(dhcp_lif_t *); 201*3431Scarlsonj dhcp_lif_t *attach_lif(const char *, boolean_t, int *); 202*3431Scarlsonj int set_lif_dhcp(dhcp_lif_t *, boolean_t); 203*3431Scarlsonj void set_lif_deprecated(dhcp_lif_t *); 204*3431Scarlsonj boolean_t clear_lif_deprecated(dhcp_lif_t *); 205*3431Scarlsonj boolean_t open_ip_lif(dhcp_lif_t *); 206*3431Scarlsonj void close_ip_lif(dhcp_lif_t *); 207*3431Scarlsonj void lif_mark_decline(dhcp_lif_t *, const char *); 208*3431Scarlsonj boolean_t schedule_lif_timer(dhcp_lif_t *, dhcp_timer_t *, 2090Sstevel@tonic-gate iu_tq_callback_t *); 210*3431Scarlsonj void cancel_lif_timers(dhcp_lif_t *); 211*3431Scarlsonj dhcp_expire_t expired_lif_state(dhcp_smach_t *); 212*3431Scarlsonj dhcp_lif_t *find_expired_lif(dhcp_smach_t *); 213*3431Scarlsonj 214*3431Scarlsonj uint_t get_max_mtu(boolean_t); 215*3431Scarlsonj void remove_v6_strays(void); 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate #ifdef __cplusplus 2180Sstevel@tonic-gate } 2190Sstevel@tonic-gate #endif 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate #endif /* INTERFACE_H */ 222