Home | History | Annotate | Download | only in inet
      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