ip_ndp.h revision 3efde6d032b3bcd6957e912c3f2a59253f28a9dc
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _INET_IP_NDP_H
#define _INET_IP_NDP_H
/*
* 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
/*
* callbacks set up with ip2mac interface, waiting for result
* of neighbor resolution.
*/
typedef struct nce_cb_s {
void *nce_cb_id;
void *nce_cb_arg;
} nce_cb_t;
#define NCE_CB_DISPATCHED 0x00000001
/*
* 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 */
/* as their local address */
} 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, ips_ndp4 and ips_ndp6.
* ips_ndp6 contains the data structures needed for IPv6 Neighbor Discovery.
* ips_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, nce_last, and nce_cb_walker_cnt.
* 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().
*
* When the link-layer address of some onlink host changes, ARP will send
* an AR_CN_ANNOUNCE message to ip so that stale neighbor-cache
* information will not get used. This message is processed in ip_arp_news()
* by walking the nce list, and updating as appropriate. The ndp_g_hw_change
* flag is set by ip_arp_news() to notify nce_t users that ip_arp_news() is
* in progress.
*/
typedef struct ndp_g_s {
int ndp_g_walker; /* # of active thread walking hash list */
int ndp_g_hw_change; /* non-zero if nce flush in progress */
} ndp_g_t;
#define NDP_HW_CHANGE_INCR(ndp) { \
(ndp)->ndp_g_hw_change++; \
}
#define NDP_HW_CHANGE_DECR(ndp) { \
(ndp)->ndp_g_hw_change--; \
}
/* nce_flags */
#define NCE_F_PERMANENT 0x1
#define NCE_F_MAPPING 0x2
#define NCE_F_ISROUTER 0x4
/* unused 0x8 */
#define NCE_F_NONUD 0x10
#define NCE_F_ANYCAST 0x20
#define NCE_F_CONDEMNED 0x40
#define NCE_F_UNSOL_ADV 0x80
#define NCE_F_BCAST 0x100
#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
#define NDP_PROBE 0x10
/* Number of packets queued in NDP for a neighbor */
#define ND_MAX_Q 4
#ifdef 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 */
/*
* Structure for nce_delete_hw_changed; specifies an IPv4 address to link-layer
* address mapping. Any route that has a cached copy of a mapping for that
* IPv4 address that doesn't match the given mapping must be purged.
*/
typedef struct {
} nce_hw_map_t;
/* 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.
*/
/* NDP Cache Entry Hash Table */
#define NCE_TABLE_SIZE 256
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);
extern void ndp_do_recovery(ipif_t *);
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 nce_delete_hw_changed(nce_t *, void *);
extern void nce_fastpath(nce_t *);
nce_t **);
extern int ndp_lookup_then_add_v4(ill_t *,
extern void ip_ndp_resolve(nce_t *);
#ifdef DEBUG
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 */