ip_ndp.h revision c793af95640863cd29868fc7c419c5d2496b207b
/*
* 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
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _INET_IP_NDP_H
#define _INET_IP_NDP_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Internal definitions for the kernel implementation of the IPv6
* Neighbor Discovery Protocol (NDP).
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _KERNEL
#define NCE_TABLE_SIZE 256
/* NDP Cache Entry */
typedef struct nce_s {
/* entry to respond to requests for a group of addresses, for */
/* instantance multicast addresses */
#define nce_first_mp_to_free nce_fp_mp
#define nce_last_mp_to_free nce_qd_mp
/* this field protects */
int nce_unsolicit_count; /* Unsolicited Adv count */
#ifdef NCE_DEBUG
#endif
} nce_t;
/*
* The ndp_g_t structure contains protocol specific information needed
* to synchronize and manage neighbor cache entries for IPv4 and IPv6.
* There are 2 such structures, ndp4 and ndp6.
* ndp6 contains the data structures needed for IPv6 Neighbor Discovery.
* ndp4 has IPv4 link layer info in its nce_t structures
* Note that the nce_t is not currently used as the arp cache itself;
* it is used for the following purposes:
* - queue packets in nce_qd_mp while waiting for arp resolution to complete
* - track state of ARP resolution in the nce_state;
*
* Locking notes:
* ndp_g_lock protects neighbor cache tables access and
* nce_lock protects nce_pcnt, nce_rcnt, nce_qd_mp nce_state,
* nce_res_mp, nce_refcnt and nce_last.
* nce_refcnt is incremented for every ire pointing to this nce and
* every time ndp_lookup() finds an nce.
* Should there be a need to obtain nce_lock and ndp_g_lock, ndp_g_lock is
* acquired first.
* To avoid becoming exclusive when deleting NCEs, ndp_walk() routine holds
* the ndp_g_lock (i.e global lock) and marks NCEs to be deleted with
* NCE_F_CONDEMNED. When all active users of such NCEs are gone the walk
* routine passes a list for deletion to nce_ire_delete_list().
*/
typedef struct ndp_g_s {
int ndp_g_walker; /* # of active thread walking hash list */
} ndp_g_t;
/* nce_flags */
#define NCE_F_PERMANENT 0x1
#define NCE_F_MAPPING 0x2
#define NCE_F_ISROUTER 0x4
#define NCE_F_PROXY 0x8
#define NCE_F_NONUD 0x10
#define NCE_F_ANYCAST 0x20
#define NCE_F_CONDEMNED 0x40
#define NCE_F_UNSOL_ADV 0x80
#define NCE_EXTERNAL_FLAGS_MASK \
/* State REACHABLE, STALE, DELAY or PROBE */
#define NCE_ISREACHABLE(nce) \
#define NDP_UNICAST 0x1
#define NDP_ISROUTER 0x2
#define NDP_SOLICITED 0x4
#define NDP_ORIDE 0x8
/* Number of packets queued in NDP for a neighbor */
#define ND_MAX_Q 4
#ifdef NCE_DEBUG
#else
#define NCE_TRACE_REF(nce)
#define NCE_UNTRACE_REF(nce)
#endif
#define NCE_REFHOLD(nce) { \
(nce)->nce_refcnt++; \
NCE_TRACE_REF(nce); \
}
#define NCE_REFHOLD_NOTR(nce) { \
(nce)->nce_refcnt++; \
}
#define NCE_REFHOLD_LOCKED(nce) { \
(nce)->nce_refcnt++; \
NCE_TRACE_REF(nce); \
}
/* nce_inactive destroys the mutex thus no mutex_exit is needed */
#define NCE_REFRELE(nce) { \
NCE_UNTRACE_REF(nce); \
if (--(nce)->nce_refcnt == 0) \
ndp_inactive(nce); \
else { \
} \
}
#define NCE_REFRELE_NOTR(nce) { \
if (--(nce)->nce_refcnt == 0) \
ndp_inactive(nce); \
else { \
} \
}
if ((nce)->nce_timeout_id != 0) { \
/* Ok to untimeout bad id. we don't hold a lock. */ \
} \
/* Don't start the timer if the nce has been deleted */ \
}
/* Structure for ndp_cache_count() */
typedef struct {
int ncc_total; /* Total number of NCEs */
int ncc_host; /* NCE entries without R bit set */
/*
* Structure of ndp_cache_reclaim(). Each field is a fraction i.e. 1 means
* reclaim all, N means reclaim 1/Nth of all entries, 0 means reclaim none.
*/
typedef struct {
int ncr_host; /* Fraction for host entries */
/* When SAP is greater than zero address appears before SAP */
(sizeof (dl_unitdata_req_t)) : \
(sizeof (dl_unitdata_req_t)))
#ifdef _BIG_ENDIAN
{ \
if (abs_sap_len > 0) { \
abs_sap_len, \
abs_sap_len); \
} \
}
#else
{ \
if (abs_sap_len > 0) { \
abs_sap_len); \
} \
}
#endif
/*
* Exclusive-or the 6 bytes that are likely to contain the MAC
* address. Assumes table_size does not exceed 256.
* Assumes EUI-64 format for good hashing.
*/
extern void ndp_cache_count(nce_t *, char *);
extern void ndp_cache_reclaim(nce_t *, char *);
extern void ndp_delete(nce_t *);
extern void ndp_fastpath_flush(nce_t *, char *);
extern void ndp_inactive(nce_t *);
mblk_t *);
extern void ndp_timer(void *);
void *, boolean_t);
const void *, const void *,
extern void nce_resolv_failed(nce_t *);
extern void arp_resolv_failed(nce_t *);
extern void nce_fastpath_list_add(nce_t *);
extern void nce_fastpath_list_delete(nce_t *);
extern void nce_fastpath_list_dispatch(ill_t *,
extern void ndp_flush_qd_mp(nce_t *);
#ifdef NCE_DEBUG
extern void nce_trace_inactive(nce_t *);
extern void nce_trace_ref(nce_t *);
extern void nce_untrace_ref(nce_t *);
#endif
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _INET_IP_NDP_H */