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