/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ARP_IMPL_H #define _ARP_IMPL_H #pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { #endif #ifdef _KERNEL #include #include #include #include /* ARP kernel hash size; used for mdb support */ #define ARP_HASH_SIZE 256 /* Named Dispatch Parameter Management Structure */ typedef struct arpparam_s { uint32_t arp_param_min; uint32_t arp_param_max; uint32_t arp_param_value; char *arp_param_name; } arpparam_t; /* ARL Structure, one per link level device */ typedef struct arl_s { struct arl_s *arl_next; /* ARL chain at arl_g_head */ queue_t *arl_rq; /* Read queue pointer */ queue_t *arl_wq; /* Write queue pointer */ t_uscalar_t arl_ppa; /* DL_ATTACH parameter */ char arl_name[LIFNAMSIZ]; /* Lower level name */ mblk_t *arl_unbind_mp; mblk_t *arl_detach_mp; t_uscalar_t arl_provider_style; /* From DL_INFO_ACK */ mblk_t *arl_queue; /* Queued commands head */ mblk_t *arl_queue_tail; /* Queued commands tail */ uint32_t arl_flags; /* ARL_F_* values below */ t_uscalar_t arl_dlpi_pending; /* pending DLPI request */ mblk_t *arl_dlpi_deferred; /* Deferred DLPI messages */ uint_t arl_state; /* lower interface state */ uint_t arl_closing : 1; /* stream is closing */ uint32_t arl_index; /* instance number */ struct arlphy_s *arl_phy; /* physical info, if any */ } arl_t; /* * There is no field to get from an arl_t to an arp_stack_t, but this * macro does it. */ #define ARL_TO_ARPSTACK(_arl) (((ar_t *)(_arl)->arl_rq->q_ptr)->ar_as) /* ARL physical info structure for a link level device */ typedef struct arlphy_s { uint32_t ap_arp_hw_type; /* hardware type */ uchar_t *ap_arp_addr; /* multicast address to use */ uchar_t *ap_hw_addr; /* hardware address */ uint32_t ap_hw_addrlen; /* hardware address length */ mblk_t *ap_xmit_mp; /* DL_UNITDATA_REQ template */ t_uscalar_t ap_xmit_addroff; /* address offset in xmit_mp */ t_uscalar_t ap_xmit_sapoff; /* sap offset in xmit_mp */ t_scalar_t ap_saplen; /* sap length */ clock_t ap_defend_start; /* start of 1-hour period */ uint_t ap_defend_count; /* # of unbidden broadcasts */ uint_t ap_notifies : 1, /* handles DL_NOTE_LINK */ ap_link_down : 1; /* DL_NOTE status */ } arlphy_t; /* ARP Cache Entry */ typedef struct ace_s { struct ace_s *ace_next; /* Hash chain next pointer */ struct ace_s **ace_ptpn; /* Pointer to previous next */ struct arl_s *ace_arl; /* Associated arl */ uint32_t ace_proto; /* Protocol for this ace */ uint32_t ace_flags; uchar_t *ace_proto_addr; uint32_t ace_proto_addr_length; uchar_t *ace_proto_mask; /* Mask for matching addr */ uchar_t *ace_proto_extract_mask; /* For mappings */ uchar_t *ace_hw_addr; uint32_t ace_hw_addr_length; uint32_t ace_hw_extract_start; /* For mappings */ mblk_t *ace_mp; /* mblk we are in */ mblk_t *ace_query_mp; /* outstanding query chain */ clock_t ace_last_bcast; /* last broadcast Response */ clock_t ace_xmit_interval; int ace_xmit_count; } ace_t; #define ARPHOOK_INTERESTED_PHYSICAL_IN(as) \ (as->as_arp_physical_in_event.he_interested) #define ARPHOOK_INTERESTED_PHYSICAL_OUT(as) \ (as->as_arp_physical_out_event.he_interested) #define ARP_HOOK_IN(_hook, _event, _ilp, _hdr, _fm, _m, as) \ \ if ((_hook).he_interested) { \ hook_pkt_event_t info; \ \ info.hpe_ifp = _ilp; \ info.hpe_ofp = 0; \ info.hpe_hdr = _hdr; \ info.hpe_mp = &(_fm); \ info.hpe_mb = _m; \ if (hook_run(_event, (hook_data_t)&info, \ as->as_netstack) != 0) { \ if (_fm != NULL) { \ freemsg(_fm); \ _fm = NULL; \ } \ _hdr = NULL; \ _m = NULL; \ } else { \ _hdr = info.hpe_hdr; \ _m = info.hpe_mb; \ } \ } #define ARP_HOOK_OUT(_hook, _event, _olp, _hdr, _fm, _m, as) \ \ if ((_hook).he_interested) { \ hook_pkt_event_t info; \ \ info.hpe_ifp = 0; \ info.hpe_ofp = _olp; \ info.hpe_hdr = _hdr; \ info.hpe_mp = &(_fm); \ info.hpe_mb = _m; \ if (hook_run(_event, (hook_data_t)&info, \ as->as_netstack) != 0) { \ if (_fm != NULL) { \ freemsg(_fm); \ _fm = NULL; \ } \ _hdr = NULL; \ _m = NULL; \ } else { \ _hdr = info.hpe_hdr; \ _m = info.hpe_mb; \ } \ } #define ACE_EXTERNAL_FLAGS_MASK \ (ACE_F_PERMANENT | ACE_F_PUBLISH | ACE_F_MAPPING | ACE_F_MYADDR | \ ACE_F_AUTHORITY) /* * ARP stack instances */ struct arp_stack { netstack_t *as_netstack; /* Common netstack */ void *as_head; /* AR Instance Data List Head */ caddr_t as_nd; /* AR Named Dispatch Head */ struct arl_s *as_arl_head; /* ARL List Head */ arpparam_t *as_param_arr; /* ndd variable table */ /* ARP Cache Entry Hash Table */ ace_t *as_ce_hash_tbl[ARP_HASH_SIZE]; ace_t *as_ce_mask_entries; /* * With the introduction of netinfo (neti kernel module), * it is now possible to access data structures in the ARP module * without the code being executed in the context of the IP module, * thus there is no locking being enforced through the use of STREAMS. * as_arl_lock is used to protect as_arl_head list. */ krwlock_t as_arl_lock; uint32_t as_arp_index_counter; uint32_t as_arp_counter_wrapped; /* arp_neti.c */ hook_family_t as_arproot; /* * Hooks for ARP */ hook_event_t as_arp_physical_in_event; hook_event_t as_arp_physical_out_event; hook_event_t as_arp_nic_events; hook_event_token_t as_arp_physical_in; hook_event_token_t as_arp_physical_out; hook_event_token_t as_arpnicevents; net_data_t as_net_data; }; typedef struct arp_stack arp_stack_t; #define ARL_F_NOARP 0x01 #define ARL_S_DOWN 0x00 #define ARL_S_PENDING 0x01 #define ARL_S_UP 0x02 /* AR Structure, one per upper stream */ typedef struct ar_s { queue_t *ar_rq; /* Read queue pointer */ queue_t *ar_wq; /* Write queue pointer */ arl_t *ar_arl; /* Associated arl */ cred_t *ar_credp; /* Credentials associated w/ open */ struct ar_s *ar_arl_ip_assoc; /* ARL - IP association */ uint32_t ar_ip_acked_close : 1, /* IP has acked the close */ ar_on_ill_stream : 1; /* Module below is IP */ arp_stack_t *ar_as; } ar_t; extern void arp_hook_init(arp_stack_t *); extern void arp_hook_destroy(arp_stack_t *); extern void arp_net_init(arp_stack_t *, netstack_t *); extern void arp_net_destroy(arp_stack_t *); #endif /* _KERNEL */ #ifdef __cplusplus } #endif #endif /* _ARP_IMPL_H */