1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _ARP_IMPL_H 27 #define _ARP_IMPL_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #ifdef _KERNEL 34 35 #include <sys/types.h> 36 #include <sys/stream.h> 37 #include <net/if.h> 38 #include <sys/netstack.h> 39 40 /* ARP kernel hash size; used for mdb support */ 41 #define ARP_HASH_SIZE 256 42 43 /* Named Dispatch Parameter Management Structure */ 44 typedef struct arpparam_s { 45 uint32_t arp_param_min; 46 uint32_t arp_param_max; 47 uint32_t arp_param_value; 48 char *arp_param_name; 49 } arpparam_t; 50 51 /* ARL Structure, one per link level device */ 52 typedef struct arl_s { 53 struct arl_s *arl_next; /* ARL chain at arl_g_head */ 54 queue_t *arl_rq; /* Read queue pointer */ 55 queue_t *arl_wq; /* Write queue pointer */ 56 t_uscalar_t arl_ppa; /* DL_ATTACH parameter */ 57 char arl_name[LIFNAMSIZ]; /* Lower level name */ 58 mblk_t *arl_unbind_mp; 59 mblk_t *arl_detach_mp; 60 t_uscalar_t arl_provider_style; /* From DL_INFO_ACK */ 61 mblk_t *arl_queue; /* Queued commands head */ 62 mblk_t *arl_queue_tail; /* Queued commands tail */ 63 uint32_t arl_flags; /* ARL_F_* values below */ 64 t_uscalar_t arl_dlpi_pending; /* pending DLPI request */ 65 mblk_t *arl_dlpi_deferred; /* Deferred DLPI messages */ 66 uint_t arl_state; /* lower interface state */ 67 uint_t arl_closing : 1; /* stream is closing */ 68 uint32_t arl_index; /* instance number */ 69 struct arlphy_s *arl_phy; /* physical info, if any */ 70 } arl_t; 71 72 /* 73 * There is no field to get from an arl_t to an arp_stack_t, but this 74 * macro does it. 75 */ 76 #define ARL_TO_ARPSTACK(_arl) (((ar_t *)(_arl)->arl_rq->q_ptr)->ar_as) 77 78 /* ARL physical info structure for a link level device */ 79 typedef struct arlphy_s { 80 uint32_t ap_arp_hw_type; /* hardware type */ 81 uchar_t *ap_arp_addr; /* multicast address to use */ 82 uchar_t *ap_hw_addr; /* hardware address */ 83 uint32_t ap_hw_addrlen; /* hardware address length */ 84 mblk_t *ap_xmit_mp; /* DL_UNITDATA_REQ template */ 85 t_uscalar_t ap_xmit_addroff; /* address offset in xmit_mp */ 86 t_uscalar_t ap_xmit_sapoff; /* sap offset in xmit_mp */ 87 t_scalar_t ap_saplen; /* sap length */ 88 clock_t ap_defend_start; /* start of 1-hour period */ 89 uint_t ap_defend_count; /* # of unbidden broadcasts */ 90 uint_t ap_notifies : 1, /* handles DL_NOTE_LINK */ 91 ap_link_down : 1; /* DL_NOTE status */ 92 } arlphy_t; 93 94 /* ARP Cache Entry */ 95 typedef struct ace_s { 96 struct ace_s *ace_next; /* Hash chain next pointer */ 97 struct ace_s **ace_ptpn; /* Pointer to previous next */ 98 struct arl_s *ace_arl; /* Associated arl */ 99 uint32_t ace_proto; /* Protocol for this ace */ 100 uint32_t ace_flags; 101 uchar_t *ace_proto_addr; 102 uint32_t ace_proto_addr_length; 103 uchar_t *ace_proto_mask; /* Mask for matching addr */ 104 uchar_t *ace_proto_extract_mask; /* For mappings */ 105 uchar_t *ace_hw_addr; 106 uint32_t ace_hw_addr_length; 107 uint32_t ace_hw_extract_start; /* For mappings */ 108 mblk_t *ace_mp; /* mblk we are in */ 109 mblk_t *ace_query_mp; /* outstanding query chain */ 110 clock_t ace_last_bcast; /* last broadcast Response */ 111 clock_t ace_xmit_interval; 112 int ace_xmit_count; 113 } ace_t; 114 115 #define ARPHOOK_INTERESTED_PHYSICAL_IN(as) \ 116 (as->as_arp_physical_in_event.he_interested) 117 #define ARPHOOK_INTERESTED_PHYSICAL_OUT(as) \ 118 (as->as_arp_physical_out_event.he_interested) 119 120 #define ARP_HOOK_IN(_hook, _event, _ilp, _hdr, _fm, _m, as) \ 121 \ 122 if ((_hook).he_interested) { \ 123 hook_pkt_event_t info; \ 124 \ 125 info.hpe_protocol = as->as_net_data; \ 126 info.hpe_ifp = _ilp; \ 127 info.hpe_ofp = 0; \ 128 info.hpe_hdr = _hdr; \ 129 info.hpe_mp = &(_fm); \ 130 info.hpe_mb = _m; \ 131 if (hook_run(as->as_net_data->netd_hooks, \ 132 _event, (hook_data_t)&info) != 0) { \ 133 if (_fm != NULL) { \ 134 freemsg(_fm); \ 135 _fm = NULL; \ 136 } \ 137 _hdr = NULL; \ 138 _m = NULL; \ 139 } else { \ 140 _hdr = info.hpe_hdr; \ 141 _m = info.hpe_mb; \ 142 } \ 143 } 144 145 #define ARP_HOOK_OUT(_hook, _event, _olp, _hdr, _fm, _m, as) \ 146 \ 147 if ((_hook).he_interested) { \ 148 hook_pkt_event_t info; \ 149 \ 150 info.hpe_protocol = as->as_net_data; \ 151 info.hpe_ifp = 0; \ 152 info.hpe_ofp = _olp; \ 153 info.hpe_hdr = _hdr; \ 154 info.hpe_mp = &(_fm); \ 155 info.hpe_mb = _m; \ 156 if (hook_run(as->as_net_data->netd_hooks, \ 157 _event, (hook_data_t)&info) != 0) { \ 158 if (_fm != NULL) { \ 159 freemsg(_fm); \ 160 _fm = NULL; \ 161 } \ 162 _hdr = NULL; \ 163 _m = NULL; \ 164 } else { \ 165 _hdr = info.hpe_hdr; \ 166 _m = info.hpe_mb; \ 167 } \ 168 } 169 170 #define ACE_EXTERNAL_FLAGS_MASK \ 171 (ACE_F_PERMANENT | ACE_F_PUBLISH | ACE_F_MAPPING | ACE_F_MYADDR | \ 172 ACE_F_AUTHORITY) 173 174 /* 175 * ARP stack instances 176 */ 177 struct arp_stack { 178 netstack_t *as_netstack; /* Common netstack */ 179 void *as_head; /* AR Instance Data List Head */ 180 caddr_t as_nd; /* AR Named Dispatch Head */ 181 struct arl_s *as_arl_head; /* ARL List Head */ 182 arpparam_t *as_param_arr; /* ndd variable table */ 183 184 /* ARP Cache Entry Hash Table */ 185 ace_t *as_ce_hash_tbl[ARP_HASH_SIZE]; 186 ace_t *as_ce_mask_entries; 187 188 /* 189 * With the introduction of netinfo (neti kernel module), 190 * it is now possible to access data structures in the ARP module 191 * without the code being executed in the context of the IP module, 192 * thus there is no locking being enforced through the use of STREAMS. 193 * as_arl_lock is used to protect as_arl_head list. 194 */ 195 krwlock_t as_arl_lock; 196 197 uint32_t as_arp_index_counter; 198 uint32_t as_arp_counter_wrapped; 199 200 /* arp_neti.c */ 201 hook_family_t as_arproot; 202 203 /* 204 * Hooks for ARP 205 */ 206 hook_event_t as_arp_physical_in_event; 207 hook_event_t as_arp_physical_out_event; 208 hook_event_t as_arp_nic_events; 209 210 hook_event_token_t as_arp_physical_in; 211 hook_event_token_t as_arp_physical_out; 212 hook_event_token_t as_arpnicevents; 213 214 net_handle_t as_net_data; 215 }; 216 typedef struct arp_stack arp_stack_t; 217 218 #define ARL_F_NOARP 0x01 219 220 #define ARL_S_DOWN 0x00 221 #define ARL_S_PENDING 0x01 222 #define ARL_S_UP 0x02 223 224 /* AR Structure, one per upper stream */ 225 typedef struct ar_s { 226 queue_t *ar_rq; /* Read queue pointer */ 227 queue_t *ar_wq; /* Write queue pointer */ 228 arl_t *ar_arl; /* Associated arl */ 229 cred_t *ar_credp; /* Credentials associated w/ open */ 230 struct ar_s *ar_arl_ip_assoc; /* ARL - IP association */ 231 uint32_t 232 ar_ip_acked_close : 1, /* IP has acked the close */ 233 ar_on_ill_stream : 1; /* Module below is IP */ 234 arp_stack_t *ar_as; 235 } ar_t; 236 237 extern void arp_hook_init(arp_stack_t *); 238 extern void arp_hook_destroy(arp_stack_t *); 239 extern void arp_net_init(arp_stack_t *, netstackid_t); 240 extern void arp_net_destroy(arp_stack_t *); 241 242 #endif /* _KERNEL */ 243 244 #ifdef __cplusplus 245 } 246 #endif 247 248 #endif /* _ARP_IMPL_H */ 249