1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #ifndef INTERFACE_H 28*0Sstevel@tonic-gate #define INTERFACE_H 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate /* 33*0Sstevel@tonic-gate * interface.[ch] encapsulate all of the agent's knowledge of network 34*0Sstevel@tonic-gate * interfaces from the DHCP agent's perspective. see interface.c 35*0Sstevel@tonic-gate * for documentation on how to use the exported functions. note that 36*0Sstevel@tonic-gate * there are not functional interfaces for manipulating all of the fields 37*0Sstevel@tonic-gate * in an ifslist -- please read the comments in the ifslist structure 38*0Sstevel@tonic-gate * definition below for the rules on accessing various fields. 39*0Sstevel@tonic-gate */ 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate #ifdef __cplusplus 42*0Sstevel@tonic-gate extern "C" { 43*0Sstevel@tonic-gate #endif 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate #include <netinet/in.h> 46*0Sstevel@tonic-gate #include <sys/socket.h> 47*0Sstevel@tonic-gate #include <net/if.h> /* IFNAMSIZ */ 48*0Sstevel@tonic-gate #include <sys/types.h> 49*0Sstevel@tonic-gate #include <netinet/dhcp.h> 50*0Sstevel@tonic-gate #include <dhcpagent_ipc.h> 51*0Sstevel@tonic-gate #include <libinetutil.h> 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate #include "async.h" 54*0Sstevel@tonic-gate #include "agent.h" 55*0Sstevel@tonic-gate #include "dlpi_io.h" 56*0Sstevel@tonic-gate #include "ipc_action.h" 57*0Sstevel@tonic-gate #include "packet.h" 58*0Sstevel@tonic-gate #include "util.h" 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate enum { DHCP_T1_TIMER, DHCP_T2_TIMER, DHCP_LEASE_TIMER }; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate typedef int script_callback_t (struct ifslist *, const char *); 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate struct ifslist { 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate /* 67*0Sstevel@tonic-gate * ifslist chain pointers, maintained by insert_ifs() / 68*0Sstevel@tonic-gate * remove_ifs(). 69*0Sstevel@tonic-gate */ 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate struct ifslist *next; 72*0Sstevel@tonic-gate struct ifslist *prev; 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate /* 75*0Sstevel@tonic-gate * hold count on this ifslist, maintained by hold_ifs() / 76*0Sstevel@tonic-gate * release_ifs() -- see below for a discussion of ifs memory 77*0Sstevel@tonic-gate * management. 78*0Sstevel@tonic-gate */ 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate uchar_t if_hold_count; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate /* 83*0Sstevel@tonic-gate * each interface can have at most one pending asynchronous 84*0Sstevel@tonic-gate * action, which is represented in a `struct async_action'. 85*0Sstevel@tonic-gate * if that asynchronous action was a result of a user request, 86*0Sstevel@tonic-gate * then the `struct ipc_action' is used to hold information 87*0Sstevel@tonic-gate * about the user request. these structures are opaque to 88*0Sstevel@tonic-gate * users of the ifslist, and the functional interfaces 89*0Sstevel@tonic-gate * provided in async.[ch] and ipc_action.[ch] should be used 90*0Sstevel@tonic-gate * to maintain them. 91*0Sstevel@tonic-gate */ 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate struct ipc_action if_ia; 94*0Sstevel@tonic-gate struct async_action if_async; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate /* 97*0Sstevel@tonic-gate * current state of the interface 98*0Sstevel@tonic-gate */ 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate DHCPSTATE if_state; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate /* 103*0Sstevel@tonic-gate * flags specific to DHCP (see dhcpagent_ipc.h) 104*0Sstevel@tonic-gate */ 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate uint16_t if_dflags; 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate /* 109*0Sstevel@tonic-gate * general interface information -- this information is initialized 110*0Sstevel@tonic-gate * in insert_ifs() and does not change over the lifetime of the 111*0Sstevel@tonic-gate * interface. 112*0Sstevel@tonic-gate */ 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate char if_name[IFNAMSIZ]; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate uint16_t if_max; /* largest DHCP packet on this if */ 117*0Sstevel@tonic-gate uint16_t if_min; /* minimum mtu size on this if */ 118*0Sstevel@tonic-gate uint16_t if_opt; /* amount of space for options in PKT */ 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate uchar_t *if_hwaddr; /* our link-layer address */ 121*0Sstevel@tonic-gate uchar_t if_hwlen; /* our link-layer address len */ 122*0Sstevel@tonic-gate uchar_t if_hwtype; /* type of link-layer */ 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate uchar_t *if_cid; /* client id, if set in defaults file */ 125*0Sstevel@tonic-gate uchar_t if_cidlen; /* client id len */ 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate uchar_t *if_prl; /* if non-NULL, param request list */ 128*0Sstevel@tonic-gate uchar_t if_prllen; /* param request list len */ 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate /* 131*0Sstevel@tonic-gate * the destination address is the broadcast address of 132*0Sstevel@tonic-gate * the interface, in DLPI terms (which means it 133*0Sstevel@tonic-gate * includes both a link-layer broadcast address and a 134*0Sstevel@tonic-gate * sap, and the order isn't consistent.) fun, huh? 135*0Sstevel@tonic-gate * blame AT&T. we store it as a token like this 136*0Sstevel@tonic-gate * because it's generally how we need to use it. we 137*0Sstevel@tonic-gate * can pull it apart using the saplen and sap_before 138*0Sstevel@tonic-gate * fields below. 139*0Sstevel@tonic-gate */ 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate uchar_t *if_daddr; /* our destination address */ 142*0Sstevel@tonic-gate uchar_t if_dlen; /* our destination address len */ 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate uchar_t if_saplen; /* the SAP len */ 145*0Sstevel@tonic-gate uchar_t if_sap_before; /* does SAP come before address? */ 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate /* 148*0Sstevel@tonic-gate * network descriptors; one is used for the DLPI 149*0Sstevel@tonic-gate * traffic before we have our IP address configured; 150*0Sstevel@tonic-gate * the other two are used afterwards. there have to 151*0Sstevel@tonic-gate * be two socket descriptors since: 152*0Sstevel@tonic-gate * 153*0Sstevel@tonic-gate * o we need one to be bound to IPPORT_BOOTPC and 154*0Sstevel@tonic-gate * and INADDR_BROADCAST, so it can receive all 155*0Sstevel@tonic-gate * broadcast traffic. this is if_sock_fd. it 156*0Sstevel@tonic-gate * is also used as a general descriptor to perform 157*0Sstevel@tonic-gate * socket-related ioctls on, like SIOCGIFFLAGS. 158*0Sstevel@tonic-gate * 159*0Sstevel@tonic-gate * o we need another to be bound to IPPORT_BOOTPC and 160*0Sstevel@tonic-gate * the IP address given to us by the DHCP server, 161*0Sstevel@tonic-gate * so we can guarantee the IP address of outgoing 162*0Sstevel@tonic-gate * packets when multihomed. (the problem being that 163*0Sstevel@tonic-gate * if a packet goes out with the wrong IP address, 164*0Sstevel@tonic-gate * then the server's response will come back on the 165*0Sstevel@tonic-gate * wrong interface). this is if_sock_ip_fd. 166*0Sstevel@tonic-gate * 167*0Sstevel@tonic-gate * note that if_sock_fd is created in init_ifs() but 168*0Sstevel@tonic-gate * not bound until dhcp_bound(); this is because we 169*0Sstevel@tonic-gate * cannot even bind to the broadcast address until we 170*0Sstevel@tonic-gate * have an IP address. 171*0Sstevel@tonic-gate * 172*0Sstevel@tonic-gate * if_sock_ip_fd isn't created until dhcp_bound(), 173*0Sstevel@tonic-gate * since we don't need it until then and we can't 174*0Sstevel@tonic-gate * bind it until after we have an IP address anyway. 175*0Sstevel@tonic-gate * 176*0Sstevel@tonic-gate * both socket descriptors are closed in reset_ifs(). 177*0Sstevel@tonic-gate */ 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate int if_dlpi_fd; 180*0Sstevel@tonic-gate int if_sock_fd; 181*0Sstevel@tonic-gate int if_sock_ip_fd; 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate /* 184*0Sstevel@tonic-gate * the following fields are set when a lease is acquired, and 185*0Sstevel@tonic-gate * may be updated over the lifetime of the lease. they are 186*0Sstevel@tonic-gate * all reset by reset_ifs(). 187*0Sstevel@tonic-gate */ 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate iu_timer_id_t if_timer[3]; /* T1, T2, and LEASE timers */ 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate lease_t if_t1; /* relative renewal start time, hbo */ 192*0Sstevel@tonic-gate lease_t if_t2; /* relative rebinding start time, hbo */ 193*0Sstevel@tonic-gate lease_t if_lease; /* relative expire time, hbo */ 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate unsigned int if_nrouters; /* the number of default routers */ 196*0Sstevel@tonic-gate struct in_addr *if_routers; /* an array of default routers */ 197*0Sstevel@tonic-gate struct in_addr if_server; /* our DHCP server, nbo */ 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate /* 200*0Sstevel@tonic-gate * while in any states except ADOPTING, INIT, INFORMATION and 201*0Sstevel@tonic-gate * INFORM_SENT, the following three fields are equal to what 202*0Sstevel@tonic-gate * we believe the current address, netmask, and broadcast 203*0Sstevel@tonic-gate * address on the interface to be. this is so we can detect 204*0Sstevel@tonic-gate * if the user changes them and abandon the interface. 205*0Sstevel@tonic-gate */ 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate struct in_addr if_addr; /* our IP address, nbo */ 208*0Sstevel@tonic-gate struct in_addr if_netmask; /* our netmask, nbo */ 209*0Sstevel@tonic-gate struct in_addr if_broadcast; /* our broadcast address, nbo */ 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate PKT_LIST *if_ack; /* ACK from the server */ 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate /* 214*0Sstevel@tonic-gate * We retain the very first ack obtained on the interface to 215*0Sstevel@tonic-gate * provide access to options which were originally assigned by 216*0Sstevel@tonic-gate * the server but may not have been included in subsequent 217*0Sstevel@tonic-gate * acks, as there are servers which do this and customers have 218*0Sstevel@tonic-gate * had unsatisfactory results when using our agent with them. 219*0Sstevel@tonic-gate * ipc_event() in agent.c provides a fallback to the original 220*0Sstevel@tonic-gate * ack when the current ack doesn't have the information 221*0Sstevel@tonic-gate * requested. 222*0Sstevel@tonic-gate */ 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate PKT_LIST *if_orig_ack; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate /* 227*0Sstevel@tonic-gate * other miscellaneous variables set or needed in the process 228*0Sstevel@tonic-gate * of acquiring a lease. 229*0Sstevel@tonic-gate */ 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate int if_offer_wait; /* seconds between offers */ 232*0Sstevel@tonic-gate iu_event_id_t if_offer_id; /* event offer id */ 233*0Sstevel@tonic-gate iu_event_id_t if_acknak_id; /* event acknak id */ 234*0Sstevel@tonic-gate iu_event_id_t if_acknak_bcast_id; 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate /* 237*0Sstevel@tonic-gate * `if_neg_monosec' represents the time since lease 238*0Sstevel@tonic-gate * acquisition or renewal began, and is used for 239*0Sstevel@tonic-gate * computing the pkt->secs field. `if_newstart_monosec' 240*0Sstevel@tonic-gate * represents the time the ACKed REQUEST was sent, 241*0Sstevel@tonic-gate * which represents the start time of a new lease. 242*0Sstevel@tonic-gate * when the lease actually begins (and thus becomes 243*0Sstevel@tonic-gate * current), `if_curstart_monosec' is set to 244*0Sstevel@tonic-gate * `if_newstart_monosec'. 245*0Sstevel@tonic-gate */ 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate monosec_t if_neg_monosec; 248*0Sstevel@tonic-gate monosec_t if_newstart_monosec; 249*0Sstevel@tonic-gate monosec_t if_curstart_monosec; 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate /* 252*0Sstevel@tonic-gate * time we sent the DISCOVER relative to if_neg_monosec, 253*0Sstevel@tonic-gate * so that the REQUEST can have the same pkt->secs. 254*0Sstevel@tonic-gate */ 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate uint16_t if_disc_secs; 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate /* 259*0Sstevel@tonic-gate * the host name we've been asked to request is remembered 260*0Sstevel@tonic-gate * here between the DISCOVER and the REQUEST 261*0Sstevel@tonic-gate */ 262*0Sstevel@tonic-gate char *if_reqhost; 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate /* 265*0Sstevel@tonic-gate * this is a chain of packets which have been received on this 266*0Sstevel@tonic-gate * interface over some interval of time. the packets may have 267*0Sstevel@tonic-gate * to meet some criteria in order to be put on this list. in 268*0Sstevel@tonic-gate * general, packets are put on this list through recv_pkt() 269*0Sstevel@tonic-gate */ 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate PKT_LIST *if_recv_pkt_list; 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate /* 274*0Sstevel@tonic-gate * these three fields are initially zero, and get incremented 275*0Sstevel@tonic-gate * as the ifslist goes from INIT -> BOUND. if and when the 276*0Sstevel@tonic-gate * ifslist moves to the RENEWING state, these fields are 277*0Sstevel@tonic-gate * reset, so they always either indicate the number of packets 278*0Sstevel@tonic-gate * sent, received, and declined while obtaining the current 279*0Sstevel@tonic-gate * lease (if BOUND), or the number of packets sent, received, 280*0Sstevel@tonic-gate * and declined while attempting to obtain a future lease 281*0Sstevel@tonic-gate * (if any other state). 282*0Sstevel@tonic-gate */ 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate uint32_t if_sent; 285*0Sstevel@tonic-gate uint32_t if_received; 286*0Sstevel@tonic-gate uint32_t if_bad_offers; 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate /* 289*0Sstevel@tonic-gate * if_send_pkt.pkt is dynamically allocated to be as big a 290*0Sstevel@tonic-gate * packet as we can send out on this interface. the remainder 291*0Sstevel@tonic-gate * of this information is needed to make it easy to handle 292*0Sstevel@tonic-gate * retransmissions. note that other than if_bad_offers, all 293*0Sstevel@tonic-gate * of these fields are maintained internally in send_pkt(), 294*0Sstevel@tonic-gate * and consequently should never need to be modified by any 295*0Sstevel@tonic-gate * other functions. 296*0Sstevel@tonic-gate */ 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate dhcp_pkt_t if_send_pkt; 299*0Sstevel@tonic-gate uint32_t if_send_timeout; 300*0Sstevel@tonic-gate struct sockaddr_in if_send_dest; 301*0Sstevel@tonic-gate stop_func_t *if_send_stop_func; 302*0Sstevel@tonic-gate uint32_t if_packet_sent; 303*0Sstevel@tonic-gate iu_timer_id_t if_retrans_timer; 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate int if_script_fd; 306*0Sstevel@tonic-gate pid_t if_script_pid; 307*0Sstevel@tonic-gate pid_t if_script_helper_pid; 308*0Sstevel@tonic-gate const char *if_script_event; 309*0Sstevel@tonic-gate iu_event_id_t if_script_event_id; 310*0Sstevel@tonic-gate const char *if_callback_msg; 311*0Sstevel@tonic-gate script_callback_t *if_script_callback; 312*0Sstevel@tonic-gate }; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate /* 315*0Sstevel@tonic-gate * a word on memory management and ifslists: 316*0Sstevel@tonic-gate * 317*0Sstevel@tonic-gate * since ifslists are often passed as context to callback functions, 318*0Sstevel@tonic-gate * they cannot be freed when the interface they represent is dropped 319*0Sstevel@tonic-gate * or released (or when those callbacks finally go off, they will be 320*0Sstevel@tonic-gate * hosed). to handle this situation, ifslists are reference counted. 321*0Sstevel@tonic-gate * here are the rules for managing ifslists: 322*0Sstevel@tonic-gate * 323*0Sstevel@tonic-gate * an ifslist is created through insert_ifs(). along with 324*0Sstevel@tonic-gate * initializing the ifslist, this puts a hold on the ifslist through 325*0Sstevel@tonic-gate * hold_ifs(). 326*0Sstevel@tonic-gate * 327*0Sstevel@tonic-gate * whenever an ifslist is released or dropped (implicitly or 328*0Sstevel@tonic-gate * explicitly), remove_ifs() is called, which sets the DHCP_IF_REMOVED 329*0Sstevel@tonic-gate * flag and removes the interface from the internal list of managed 330*0Sstevel@tonic-gate * interfaces. lastly, remove_ifs() calls release_ifs() to remove the 331*0Sstevel@tonic-gate * hold acquired in insert_ifs(). if this decrements the hold count 332*0Sstevel@tonic-gate * on the interface to zero, then free_ifs() is called. if there are 333*0Sstevel@tonic-gate * holds other than the hold acquired in insert_ifs(), the hold count 334*0Sstevel@tonic-gate * will still be > 0, and the interface will remain allocated (though 335*0Sstevel@tonic-gate * dormant). 336*0Sstevel@tonic-gate * 337*0Sstevel@tonic-gate * whenever a callback is scheduled against an ifslist, another hold 338*0Sstevel@tonic-gate * must be put on the ifslist through hold_ifs(). 339*0Sstevel@tonic-gate * 340*0Sstevel@tonic-gate * whenever a callback is called back against an ifslist, 341*0Sstevel@tonic-gate * release_ifs() must be called to decrement the hold count, which may 342*0Sstevel@tonic-gate * end up freeing the ifslist if the hold count becomes zero. 343*0Sstevel@tonic-gate * 344*0Sstevel@tonic-gate * if release_ifs() returns 0, then there are no remaining holds 345*0Sstevel@tonic-gate * against this ifslist, and the ifslist in fact no longer exists. 346*0Sstevel@tonic-gate * 347*0Sstevel@tonic-gate * since some callbacks may take a long time to get called back (such 348*0Sstevel@tonic-gate * as timeout callbacks for lease expiration, etc), it is sometimes 349*0Sstevel@tonic-gate * more appropriate to cancel the callbacks and call release_ifs() if 350*0Sstevel@tonic-gate * the cancellation succeeds. this is done in remove_ifs() for the 351*0Sstevel@tonic-gate * lease, t1, and t2 callbacks. 352*0Sstevel@tonic-gate * 353*0Sstevel@tonic-gate * in general, a callback should also call verify_ifs() when it gets 354*0Sstevel@tonic-gate * called back in addition to release_ifs(), to make sure that the 355*0Sstevel@tonic-gate * interface is still in fact under the dhcpagent's control. to make 356*0Sstevel@tonic-gate * coding simpler, there is a third function, check_ifs(), which 357*0Sstevel@tonic-gate * performs both the release_ifs() and the verify_ifs(). in addition, 358*0Sstevel@tonic-gate * if check_ifs() detects that the callback has the last hold against 359*0Sstevel@tonic-gate * a given interface, it informs it instead of performing the final 360*0Sstevel@tonic-gate * release, and thus allows it to clean up appropriately before 361*0Sstevel@tonic-gate * performing the final release. 362*0Sstevel@tonic-gate */ 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gate int canonize_ifs(struct ifslist *); 365*0Sstevel@tonic-gate int check_ifs(struct ifslist *); 366*0Sstevel@tonic-gate void hold_ifs(struct ifslist *); 367*0Sstevel@tonic-gate struct ifslist *insert_ifs(const char *, boolean_t, int *); 368*0Sstevel@tonic-gate struct ifslist *lookup_ifs(const char *); 369*0Sstevel@tonic-gate struct ifslist *lookup_ifs_by_xid(uint32_t); 370*0Sstevel@tonic-gate void nuke_ifslist(boolean_t); 371*0Sstevel@tonic-gate void refresh_ifslist(iu_eh_t *, int, void *); 372*0Sstevel@tonic-gate int release_ifs(struct ifslist *); 373*0Sstevel@tonic-gate void remove_ifs(struct ifslist *); 374*0Sstevel@tonic-gate void reset_ifs(struct ifslist *); 375*0Sstevel@tonic-gate int verify_ifs(struct ifslist *); 376*0Sstevel@tonic-gate unsigned int ifs_count(void); 377*0Sstevel@tonic-gate void cancel_ifs_timers(struct ifslist *); 378*0Sstevel@tonic-gate int schedule_ifs_timer(struct ifslist *, int, uint32_t, 379*0Sstevel@tonic-gate iu_tq_callback_t *); 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate #ifdef __cplusplus 382*0Sstevel@tonic-gate } 383*0Sstevel@tonic-gate #endif 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate #endif /* INTERFACE_H */ 386