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 /* 228485SPeter.Memishian@Sun.COM * Copyright 2009 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 /* 303431Scarlsonj * Interface.[ch] encapsulate all of the agent's knowledge of network 313431Scarlsonj * interfaces from the DHCP agent's perspective. See interface.c for 323431Scarlsonj * documentation on how to use the exported functions. Note that there are not 333431Scarlsonj * functional interfaces for manipulating all of the fields in a PIF or LIF -- 343431Scarlsonj * please read the comments in the structure definitions below for the rules on 353431Scarlsonj * accessing various fields. 360Sstevel@tonic-gate */ 370Sstevel@tonic-gate 380Sstevel@tonic-gate #ifdef __cplusplus 390Sstevel@tonic-gate extern "C" { 400Sstevel@tonic-gate #endif 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include <netinet/in.h> 430Sstevel@tonic-gate #include <net/if.h> /* IFNAMSIZ */ 440Sstevel@tonic-gate #include <sys/types.h> 450Sstevel@tonic-gate #include <netinet/dhcp.h> 460Sstevel@tonic-gate #include <dhcpagent_ipc.h> 470Sstevel@tonic-gate #include <libinetutil.h> 480Sstevel@tonic-gate 493431Scarlsonj #include "common.h" 500Sstevel@tonic-gate #include "util.h" 510Sstevel@tonic-gate 523431Scarlsonj #define V4_PART_OF_V6(v6) v6._S6_un._S6_u32[3] 530Sstevel@tonic-gate 543431Scarlsonj struct dhcp_pif_s { 553431Scarlsonj dhcp_pif_t *pif_next; /* Note: must be first */ 563431Scarlsonj dhcp_pif_t *pif_prev; 573431Scarlsonj dhcp_lif_t *pif_lifs; /* pointer to logical interface list */ 583431Scarlsonj uint32_t pif_index; /* interface index */ 593431Scarlsonj uint16_t pif_max; /* largest DHCP packet on this if */ 603431Scarlsonj uchar_t *pif_hwaddr; /* our link-layer address */ 613431Scarlsonj uchar_t pif_hwlen; /* our link-layer address len */ 623431Scarlsonj uchar_t pif_hwtype; /* type of link-layer */ 633431Scarlsonj boolean_t pif_isv6; 643431Scarlsonj boolean_t pif_running; /* interface is running */ 653431Scarlsonj uint_t pif_hold_count; /* reference count */ 663431Scarlsonj char pif_name[LIFNAMSIZ]; 678485SPeter.Memishian@Sun.COM char pif_grifname[LIFNAMSIZ]; 688485SPeter.Memishian@Sun.COM uint32_t pif_grindex; /* interface index for pif_grifname */ 698485SPeter.Memishian@Sun.COM boolean_t pif_under_ipmp; /* is an ipmp underlying interface */ 703431Scarlsonj }; 710Sstevel@tonic-gate 723431Scarlsonj struct dhcp_lif_s { 733431Scarlsonj dhcp_lif_t *lif_next; /* Note: must be first */ 743431Scarlsonj dhcp_lif_t *lif_prev; 753431Scarlsonj dhcp_pif_t *lif_pif; /* backpointer to parent physical if */ 763431Scarlsonj dhcp_smach_t *lif_smachs; /* pointer to list of state machines */ 773431Scarlsonj dhcp_lease_t *lif_lease; /* backpointer to lease holding LIF */ 783431Scarlsonj uint64_t lif_flags; /* Interface flags (IFF_*) */ 793431Scarlsonj int lif_sock_ip_fd; /* Bound to addr.BOOTPC for src addr */ 805381Smeem iu_event_id_t lif_packet_id; /* event packet id */ 813431Scarlsonj uint_t lif_max; /* maximum IP message size */ 823431Scarlsonj uint_t lif_hold_count; /* reference count */ 833431Scarlsonj boolean_t lif_dad_wait; /* waiting for DAD resolution */ 843431Scarlsonj boolean_t lif_removed; /* removed from list */ 853431Scarlsonj boolean_t lif_plumbed; /* interface plumbed by dhcpagent */ 863431Scarlsonj boolean_t lif_expired; /* lease has evaporated */ 873431Scarlsonj const char *lif_declined; /* reason to refuse this address */ 883431Scarlsonj uint32_t lif_iaid; /* unique and stable identifier */ 893431Scarlsonj iu_event_id_t lif_iaid_id; /* for delayed writes to /etc */ 900Sstevel@tonic-gate 910Sstevel@tonic-gate /* 923431Scarlsonj * While in any states except ADOPTING, INIT, INFORMATION and 933431Scarlsonj * INFORM_SENT, the following three fields are equal to what we believe 943431Scarlsonj * the current address, netmask, and broadcast address on the interface 953431Scarlsonj * to be. This is so we can detect if the user changes them and 963431Scarlsonj * abandon the interface. 970Sstevel@tonic-gate */ 980Sstevel@tonic-gate 993431Scarlsonj in6_addr_t lif_v6addr; /* our IP address */ 1003431Scarlsonj in6_addr_t lif_v6mask; /* our netmask */ 1013431Scarlsonj in6_addr_t lif_v6peer; /* our broadcast or peer address */ 1020Sstevel@tonic-gate 1033431Scarlsonj dhcp_timer_t lif_preferred; /* lease preferred timer (v6 only) */ 1043431Scarlsonj dhcp_timer_t lif_expire; /* lease expire timer */ 1050Sstevel@tonic-gate 1063431Scarlsonj char lif_name[LIFNAMSIZ]; 1073431Scarlsonj }; 1083431Scarlsonj #define lif_addr V4_PART_OF_V6(lif_v6addr) 1093431Scarlsonj #define lif_netmask V4_PART_OF_V6(lif_v6mask) 1103431Scarlsonj #define lif_peer V4_PART_OF_V6(lif_v6peer) 1113431Scarlsonj #define lif_broadcast V4_PART_OF_V6(lif_v6peer) 1120Sstevel@tonic-gate 1133431Scarlsonj /* used by expired_lif_state to express state of DHCP interfaces */ 1143431Scarlsonj typedef enum dhcp_expire_e { 1153431Scarlsonj DHCP_EXP_NOLIFS, 1163431Scarlsonj DHCP_EXP_NOEXP, 1173431Scarlsonj DHCP_EXP_ALLEXP, 1183431Scarlsonj DHCP_EXP_SOMEEXP 1193431Scarlsonj } dhcp_expire_t; 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate /* 1223431Scarlsonj * A word on memory management and LIFs and PIFs: 1230Sstevel@tonic-gate * 1243431Scarlsonj * Since LIFs are often passed as context to callback functions, they cannot be 1253431Scarlsonj * freed when the interface they represent is dropped or released (or when 1263431Scarlsonj * those callbacks finally go off, they will be hosed). To handle this 1273431Scarlsonj * situation, the structures are reference counted. Here are the rules for 1283431Scarlsonj * managing these counts: 1290Sstevel@tonic-gate * 1303431Scarlsonj * A PIF is created through insert_pif(). Along with initializing the PIF, 1313431Scarlsonj * this puts a hold on the PIF. A LIF is created through insert_lif(). This 1323431Scarlsonj * also initializes the LIF and places a hold on it. The caller's hold on the 1333431Scarlsonj * underlying PIF is transferred to the LIF. 1340Sstevel@tonic-gate * 1353431Scarlsonj * Whenever a lease is released or dropped (implicitly or explicitly), 1363431Scarlsonj * remove_lif() is called, which sets the lif_removed flag and removes the 1373431Scarlsonj * interface from the internal list of managed interfaces. Lastly, 1383431Scarlsonj * remove_lif() calls release_lif() to remove the hold acquired in 1393431Scarlsonj * insert_lif(). If this decrements the hold count on the interface to zero, 1403431Scarlsonj * then free() is called and the hold on the PIF is dropped. If there are 1413431Scarlsonj * holds other than the hold acquired in insert_lif(), the hold count will 1423431Scarlsonj * still be > 0, and the interface will remain allocated (though dormant). 1430Sstevel@tonic-gate * 1443431Scarlsonj * Whenever a callback is scheduled against a LIF, another hold must be put on 1453431Scarlsonj * the ifslist through hold_lif(). 1460Sstevel@tonic-gate * 1473431Scarlsonj * Whenever a callback is called back against a LIF, release_lif() must be 1483431Scarlsonj * called to decrement the hold count, which may end up freeing the LIF if the 1493431Scarlsonj * hold count becomes zero. 1500Sstevel@tonic-gate * 1513431Scarlsonj * Since some callbacks may take a long time to get called back (such as 1523431Scarlsonj * timeout callbacks for lease expiration, etc), it is sometimes more 1533431Scarlsonj * appropriate to cancel the callbacks and call release_lif() if the 1543431Scarlsonj * cancellation succeeds. This is done in remove_lif() for the lease preferred 1553431Scarlsonj * and expire callbacks. 1563431Scarlsonj * 1573431Scarlsonj * In general, a callback may also call verify_lif() when it gets called back 1583431Scarlsonj * in addition to release_lif(), to make sure that the interface is still in 1593431Scarlsonj * fact under the dhcpagent's control. To make coding simpler, there is a 1603431Scarlsonj * third function, verify_smach(), which performs both the release_lif() and 1613431Scarlsonj * the verify_lif() on all LIFs controlled by a state machine. 1620Sstevel@tonic-gate */ 1630Sstevel@tonic-gate 1643431Scarlsonj extern dhcp_pif_t *v4root; 1653431Scarlsonj extern dhcp_pif_t *v6root; 1663431Scarlsonj 1673431Scarlsonj dhcp_pif_t *insert_pif(const char *, boolean_t, int *); 1683431Scarlsonj void hold_pif(dhcp_pif_t *); 1693431Scarlsonj void release_pif(dhcp_pif_t *); 1703431Scarlsonj dhcp_pif_t *lookup_pif_by_uindex(uint16_t, dhcp_pif_t *, boolean_t); 1713431Scarlsonj dhcp_pif_t *lookup_pif_by_name(const char *, boolean_t); 1723431Scarlsonj void pif_status(dhcp_pif_t *, boolean_t); 1733431Scarlsonj 1743431Scarlsonj dhcp_lif_t *insert_lif(dhcp_pif_t *, const char *, int *); 1753431Scarlsonj void hold_lif(dhcp_lif_t *); 1763431Scarlsonj void release_lif(dhcp_lif_t *); 1773431Scarlsonj void remove_lif(dhcp_lif_t *); 1783431Scarlsonj dhcp_lif_t *lookup_lif_by_name(const char *, const dhcp_pif_t *); 1793431Scarlsonj boolean_t verify_lif(const dhcp_lif_t *); 1803431Scarlsonj dhcp_lif_t *plumb_lif(dhcp_pif_t *, const in6_addr_t *); 1813431Scarlsonj void unplumb_lif(dhcp_lif_t *); 1823431Scarlsonj dhcp_lif_t *attach_lif(const char *, boolean_t, int *); 183*10785SPeter.Memishian@Sun.COM int set_lif_dhcp(dhcp_lif_t *); 1843431Scarlsonj void set_lif_deprecated(dhcp_lif_t *); 1853431Scarlsonj boolean_t clear_lif_deprecated(dhcp_lif_t *); 1868485SPeter.Memishian@Sun.COM boolean_t open_ip_lif(dhcp_lif_t *, in_addr_t, boolean_t); 1873431Scarlsonj void close_ip_lif(dhcp_lif_t *); 1883431Scarlsonj void lif_mark_decline(dhcp_lif_t *, const char *); 1893431Scarlsonj boolean_t schedule_lif_timer(dhcp_lif_t *, dhcp_timer_t *, 1900Sstevel@tonic-gate iu_tq_callback_t *); 1913431Scarlsonj void cancel_lif_timers(dhcp_lif_t *); 1923431Scarlsonj dhcp_expire_t expired_lif_state(dhcp_smach_t *); 1933431Scarlsonj dhcp_lif_t *find_expired_lif(dhcp_smach_t *); 1943431Scarlsonj 1953431Scarlsonj uint_t get_max_mtu(boolean_t); 1963431Scarlsonj void remove_v6_strays(void); 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate #ifdef __cplusplus 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate #endif 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate #endif /* INTERFACE_H */ 203