1*b127ac41SPhilip Kirk /* 2*b127ac41SPhilip Kirk * CDDL HEADER START 3*b127ac41SPhilip Kirk * 4*b127ac41SPhilip Kirk * The contents of this file are subject to the terms of the 5*b127ac41SPhilip Kirk * Common Development and Distribution License (the "License"). 6*b127ac41SPhilip Kirk * You may not use this file except in compliance with the License. 7*b127ac41SPhilip Kirk * 8*b127ac41SPhilip Kirk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*b127ac41SPhilip Kirk * or http://www.opensolaris.org/os/licensing. 10*b127ac41SPhilip Kirk * See the License for the specific language governing permissions 11*b127ac41SPhilip Kirk * and limitations under the License. 12*b127ac41SPhilip Kirk * 13*b127ac41SPhilip Kirk * When distributing Covered Code, include this CDDL HEADER in each 14*b127ac41SPhilip Kirk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*b127ac41SPhilip Kirk * If applicable, add the following below this CDDL HEADER, with the 16*b127ac41SPhilip Kirk * fields enclosed by brackets "[]" replaced with your own identifying 17*b127ac41SPhilip Kirk * information: Portions Copyright [yyyy] [name of copyright owner] 18*b127ac41SPhilip Kirk * 19*b127ac41SPhilip Kirk * CDDL HEADER END 20*b127ac41SPhilip Kirk */ 21*b127ac41SPhilip Kirk 22*b127ac41SPhilip Kirk /* 23*b127ac41SPhilip Kirk * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*b127ac41SPhilip Kirk * Use is subject to license terms. 25*b127ac41SPhilip Kirk */ 26*b127ac41SPhilip Kirk 27*b127ac41SPhilip Kirk #ifndef _INET_IPNET_H 28*b127ac41SPhilip Kirk #define _INET_IPNET_H 29*b127ac41SPhilip Kirk 30*b127ac41SPhilip Kirk #ifdef __cplusplus 31*b127ac41SPhilip Kirk extern "C" { 32*b127ac41SPhilip Kirk #endif 33*b127ac41SPhilip Kirk 34*b127ac41SPhilip Kirk #include <sys/types.h> 35*b127ac41SPhilip Kirk #include <sys/netstack.h> 36*b127ac41SPhilip Kirk #include <sys/list.h> 37*b127ac41SPhilip Kirk #include <netinet/in.h> 38*b127ac41SPhilip Kirk #include <net/if.h> 39*b127ac41SPhilip Kirk #include <sys/avl.h> 40*b127ac41SPhilip Kirk #include <sys/neti.h> 41*b127ac41SPhilip Kirk 42*b127ac41SPhilip Kirk /* 43*b127ac41SPhilip Kirk * Structure used to hold information for both IPv4 and IPv6 addresses. 44*b127ac41SPhilip Kirk */ 45*b127ac41SPhilip Kirk typedef struct ipnetif_addr { 46*b127ac41SPhilip Kirk union { 47*b127ac41SPhilip Kirk ipaddr_t ifau_ip4addr; 48*b127ac41SPhilip Kirk in6_addr_t ifau_ip6addr; 49*b127ac41SPhilip Kirk } ifa_addr; 50*b127ac41SPhilip Kirk ipaddr_t ifa_brdaddr; 51*b127ac41SPhilip Kirk zoneid_t ifa_zone; 52*b127ac41SPhilip Kirk uint64_t ifa_id; 53*b127ac41SPhilip Kirk list_node_t ifa_link; 54*b127ac41SPhilip Kirk } ipnetif_addr_t; 55*b127ac41SPhilip Kirk #define ifa_ip4addr ifa_addr.ifau_ip4addr 56*b127ac41SPhilip Kirk #define ifa_ip6addr ifa_addr.ifau_ip6addr 57*b127ac41SPhilip Kirk 58*b127ac41SPhilip Kirk /* 59*b127ac41SPhilip Kirk * Structure describes the ipnet module representation of an ip interface. 60*b127ac41SPhilip Kirk * The structure holds both IPv4 and IPv6 addresses, the address lists are 61*b127ac41SPhilip Kirk * protected by a mutex. The ipnetif structures are held per stack instance 62*b127ac41SPhilip Kirk * within avl trees indexed on name and ip index. 63*b127ac41SPhilip Kirk */ 64*b127ac41SPhilip Kirk typedef struct ipnetif { 65*b127ac41SPhilip Kirk char if_name[LIFNAMSIZ]; 66*b127ac41SPhilip Kirk uint_t if_flags; 67*b127ac41SPhilip Kirk uint64_t if_index; 68*b127ac41SPhilip Kirk kmutex_t if_addr_lock; /* protects both addr lists */ 69*b127ac41SPhilip Kirk list_t if_ip4addr_list; 70*b127ac41SPhilip Kirk list_t if_ip6addr_list; 71*b127ac41SPhilip Kirk avl_node_t if_avl_by_index; 72*b127ac41SPhilip Kirk avl_node_t if_avl_by_name; 73*b127ac41SPhilip Kirk dev_t if_dev; 74*b127ac41SPhilip Kirk uint_t if_multicnt; /* protected by ips_event_lock */ 75*b127ac41SPhilip Kirk kmutex_t if_reflock; /* protects if_refcnt */ 76*b127ac41SPhilip Kirk uint_t if_refcnt; 77*b127ac41SPhilip Kirk } ipnetif_t; 78*b127ac41SPhilip Kirk 79*b127ac41SPhilip Kirk /* if_flags */ 80*b127ac41SPhilip Kirk #define IPNETIF_IPV4PLUMBED 0x01 81*b127ac41SPhilip Kirk #define IPNETIF_IPV6PLUMBED 0x02 82*b127ac41SPhilip Kirk #define IPNETIF_IPV4ALLMULTI 0x04 83*b127ac41SPhilip Kirk #define IPNETIF_IPV6ALLMULTI 0x08 84*b127ac41SPhilip Kirk 85*b127ac41SPhilip Kirk /* 86*b127ac41SPhilip Kirk * Structure used by the accept callback function. This is simply an address 87*b127ac41SPhilip Kirk * pointer into a packet (either IPv4 or IPv6), along with an address family 88*b127ac41SPhilip Kirk * that denotes which pointer is valid. 89*b127ac41SPhilip Kirk */ 90*b127ac41SPhilip Kirk typedef struct ipnet_addrp { 91*b127ac41SPhilip Kirk sa_family_t iap_family; 92*b127ac41SPhilip Kirk union { 93*b127ac41SPhilip Kirk ipaddr_t *iapu_addr4; 94*b127ac41SPhilip Kirk in6_addr_t *iapu_addr6; 95*b127ac41SPhilip Kirk } iap_addrp; 96*b127ac41SPhilip Kirk } ipnet_addrp_t; 97*b127ac41SPhilip Kirk #define iap_addr4 iap_addrp.iapu_addr4 98*b127ac41SPhilip Kirk #define iap_addr6 iap_addrp.iapu_addr6 99*b127ac41SPhilip Kirk 100*b127ac41SPhilip Kirk struct ipnet; 101*b127ac41SPhilip Kirk struct ipobs_hook_data; 102*b127ac41SPhilip Kirk typedef boolean_t ipnet_acceptfn_t(struct ipnet *, struct ipobs_hook_data *, 103*b127ac41SPhilip Kirk ipnet_addrp_t *, ipnet_addrp_t *); 104*b127ac41SPhilip Kirk 105*b127ac41SPhilip Kirk /* 106*b127ac41SPhilip Kirk * Per instance data for all open streams. Instance data is held on a 107*b127ac41SPhilip Kirk * per netstack list see struct ipnet_stack below. 108*b127ac41SPhilip Kirk */ 109*b127ac41SPhilip Kirk typedef struct ipnet { 110*b127ac41SPhilip Kirk queue_t *ipnet_rq; /* read queue pointer */ 111*b127ac41SPhilip Kirk minor_t ipnet_minor; /* minor number for this instance */ 112*b127ac41SPhilip Kirk ipnetif_t *ipnet_if; /* ipnetif for this open instance */ 113*b127ac41SPhilip Kirk zoneid_t ipnet_zoneid; /* zoneid the device was opened in */ 114*b127ac41SPhilip Kirk uint16_t ipnet_flags; /* see below */ 115*b127ac41SPhilip Kirk t_scalar_t ipnet_sap; /* sap this instance is bound to */ 116*b127ac41SPhilip Kirk t_uscalar_t ipnet_dlstate; /* dlpi state */ 117*b127ac41SPhilip Kirk list_node_t ipnet_next; /* list next member */ 118*b127ac41SPhilip Kirk netstack_t *ipnet_ns; /* netstack of zone we were opened in */ 119*b127ac41SPhilip Kirk ipnet_acceptfn_t *ipnet_acceptfn; /* accept callback function pointer */ 120*b127ac41SPhilip Kirk } ipnet_t; 121*b127ac41SPhilip Kirk 122*b127ac41SPhilip Kirk /* ipnet_flags */ 123*b127ac41SPhilip Kirk #define IPNET_PROMISC_PHYS 0x01 124*b127ac41SPhilip Kirk #define IPNET_PROMISC_MULTI 0x02 125*b127ac41SPhilip Kirk #define IPNET_PROMISC_SAP 0x04 126*b127ac41SPhilip Kirk #define IPNET_INFO 0x08 127*b127ac41SPhilip Kirk #define IPNET_LOMODE 0x10 128*b127ac41SPhilip Kirk 129*b127ac41SPhilip Kirk /* 130*b127ac41SPhilip Kirk * Per-netstack data holding: 131*b127ac41SPhilip Kirk * - net_handle_t references for IPv4 and IPv6 for this netstack. 132*b127ac41SPhilip Kirk * - avl trees by name and index for ip interfaces associated with this 133*b127ac41SPhilip Kirk * netstack. The trees are protected by ips_avl_lock. 134*b127ac41SPhilip Kirk * - ips_str_list is a list of open client streams. ips_walkers_lock in 135*b127ac41SPhilip Kirk * conjunction with ips_walkers_cv and ips_walkers_cnt synchronize access to 136*b127ac41SPhilip Kirk * the list. The count is incremented in ipnet_dispatch() at the start of a 137*b127ac41SPhilip Kirk * walk and decremented when the walk is finished. If the walkers count is 0 138*b127ac41SPhilip Kirk * then we cv_broadcast() waiting any threads waiting on the walkers count. 139*b127ac41SPhilip Kirk * - ips_event_lock synchronizes ipnet_if_init() and incoming NIC info events. 140*b127ac41SPhilip Kirk * We cannot be processing any NIC info events while initializing interfaces 141*b127ac41SPhilip Kirk * in ipnet_if_init(). 142*b127ac41SPhilip Kirk * 143*b127ac41SPhilip Kirk * Note on lock ordering: If a thread needs to both hold the ips_event_lock 144*b127ac41SPhilip Kirk * and any other lock such as ips_walkers_lock, ips_avl_lock, or if_addr_lock, 145*b127ac41SPhilip Kirk * the ips_event_lock must be held first. This lock ordering is mandated by 146*b127ac41SPhilip Kirk * ipnet_nicevent_cb() which must always grab ips_event_lock before continuing 147*b127ac41SPhilip Kirk * with processing NIC events. 148*b127ac41SPhilip Kirk */ 149*b127ac41SPhilip Kirk typedef struct ipnet_stack { 150*b127ac41SPhilip Kirk net_handle_t ips_ndv4; 151*b127ac41SPhilip Kirk net_handle_t ips_ndv6; 152*b127ac41SPhilip Kirk netstack_t *ips_netstack; 153*b127ac41SPhilip Kirk hook_t *ips_nicevents; 154*b127ac41SPhilip Kirk kmutex_t ips_event_lock; 155*b127ac41SPhilip Kirk kmutex_t ips_avl_lock; 156*b127ac41SPhilip Kirk avl_tree_t ips_avl_by_index; 157*b127ac41SPhilip Kirk avl_tree_t ips_avl_by_name; 158*b127ac41SPhilip Kirk kmutex_t ips_walkers_lock; 159*b127ac41SPhilip Kirk kcondvar_t ips_walkers_cv; 160*b127ac41SPhilip Kirk uint_t ips_walkers_cnt; 161*b127ac41SPhilip Kirk list_t ips_str_list; 162*b127ac41SPhilip Kirk uint64_t ips_drops; 163*b127ac41SPhilip Kirk } ipnet_stack_t; 164*b127ac41SPhilip Kirk 165*b127ac41SPhilip Kirk /* 166*b127ac41SPhilip Kirk * Template for dl_info_ack_t initialization. We don't have an address, so we 167*b127ac41SPhilip Kirk * set the address length to just the SAP length (16 bits). We don't really 168*b127ac41SPhilip Kirk * have a maximum SDU, but setting it to UINT_MAX proved problematic with 169*b127ac41SPhilip Kirk * applications that performed arithmetic on dl_max_sdu and wrapped around, so 170*b127ac41SPhilip Kirk * we sleaze out and use INT_MAX. 171*b127ac41SPhilip Kirk */ 172*b127ac41SPhilip Kirk #define IPNET_INFO_ACK_INIT { \ 173*b127ac41SPhilip Kirk DL_INFO_ACK, /* dl_primitive */ \ 174*b127ac41SPhilip Kirk INT_MAX, /* dl_max_sdu */ \ 175*b127ac41SPhilip Kirk 0, /* dl_min_sdu */ \ 176*b127ac41SPhilip Kirk sizeof (uint16_t), /* dl_addr_length */ \ 177*b127ac41SPhilip Kirk DL_IPNET, /* dl_mac_type */ \ 178*b127ac41SPhilip Kirk 0, /* dl_reserved */ \ 179*b127ac41SPhilip Kirk 0, /* dl_current_state */ \ 180*b127ac41SPhilip Kirk sizeof (uint16_t), /* dl_sap_length */ \ 181*b127ac41SPhilip Kirk DL_CLDLS, /* dl_service_mode */ \ 182*b127ac41SPhilip Kirk 0, /* dl_qos_length */ \ 183*b127ac41SPhilip Kirk 0, /* dl_qos_offset */ \ 184*b127ac41SPhilip Kirk 0, /* dl_range_length */ \ 185*b127ac41SPhilip Kirk 0, /* dl_range_offset */ \ 186*b127ac41SPhilip Kirk DL_STYLE1, /* dl_provider_style */ \ 187*b127ac41SPhilip Kirk 0, /* dl_addr_offset */ \ 188*b127ac41SPhilip Kirk DL_VERSION_2, /* dl_version */ \ 189*b127ac41SPhilip Kirk 0, /* dl_brdcst_addr_length */ \ 190*b127ac41SPhilip Kirk 0 /* dl_brdcst_addr_offset */ \ 191*b127ac41SPhilip Kirk } 192*b127ac41SPhilip Kirk 193*b127ac41SPhilip Kirk typedef void ipnet_walkfunc_t(const char *, void *, dev_t); 194*b127ac41SPhilip Kirk extern void ipnet_walk_if(ipnet_walkfunc_t *, void *, zoneid_t); 195*b127ac41SPhilip Kirk extern dev_t ipnet_if_getdev(char *, zoneid_t); 196*b127ac41SPhilip Kirk 197*b127ac41SPhilip Kirk #ifdef __cplusplus 198*b127ac41SPhilip Kirk } 199*b127ac41SPhilip Kirk #endif 200*b127ac41SPhilip Kirk 201*b127ac41SPhilip Kirk #endif /* _INET_IPNET_H */ 202