if_llatbl.h revision 238990
1158979Snetchild/*
2166322Sjoel * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
3166322Sjoel * Copyright (c) 2004-2008 Qing Li. All rights reserved.
4166322Sjoel * Copyright (c) 2008 Kip Macy. All rights reserved.
5158979Snetchild *
6166322Sjoel * Redistribution and use in source and binary forms, with or without
7166322Sjoel * modification, are permitted provided that the following conditions
8166322Sjoel * are met:
9166322Sjoel * 1. Redistributions of source code must retain the above copyright
10166322Sjoel *    notice, this list of conditions and the following disclaimer.
11166322Sjoel * 2. Redistributions in binary form must reproduce the above copyright
12166322Sjoel *    notice, this list of conditions and the following disclaimer in the
13166322Sjoel *    documentation and/or other materials provided with the distribution.
14166322Sjoel *
15166322Sjoel * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16166322Sjoel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17166322Sjoel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18166322Sjoel * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19166322Sjoel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20166322Sjoel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21166322Sjoel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22158979Snetchild * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23158979Snetchild * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24158979Snetchild * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25158979Snetchild * SUCH DAMAGE.
26158979Snetchild */
27158979Snetchild#include <sys/cdefs.h>
28158979Snetchild__FBSDID("$FreeBSD: head/sys/net/if_llatbl.h 238990 2012-08-02 13:57:49Z glebius $");
29158979Snetchild
30158979Snetchild#ifndef	_NET_IF_LLATBL_H_
31158979Snetchild#define	_NET_IF_LLATBL_H_
32158979Snetchild
33158979Snetchild#include "opt_ofed.h"
34158979Snetchild
35158979Snetchild#include <sys/_rwlock.h>
36158979Snetchild#include <netinet/in.h>
37158979Snetchild
38158979Snetchildstruct ifnet;
39158979Snetchildstruct sysctl_req;
40158979Snetchildstruct rt_msghdr;
41158979Snetchildstruct rt_addrinfo;
42158979Snetchild
43158979Snetchildstruct llentry;
44158979SnetchildLIST_HEAD(llentries, llentry);
45158979Snetchild
46158979Snetchildextern struct rwlock lltable_rwlock;
47158979Snetchild#define	LLTABLE_RLOCK()		rw_rlock(&lltable_rwlock)
48158979Snetchild#define	LLTABLE_RUNLOCK()	rw_runlock(&lltable_rwlock)
49158979Snetchild#define	LLTABLE_WLOCK()		rw_wlock(&lltable_rwlock)
50158979Snetchild#define	LLTABLE_WUNLOCK()	rw_wunlock(&lltable_rwlock)
51158979Snetchild#define	LLTABLE_LOCK_ASSERT()	rw_assert(&lltable_rwlock, RA_LOCKED)
52158979Snetchild
53158979Snetchild/*
54158979Snetchild * Code referencing llentry must at least hold
55158979Snetchild * a shared lock
56158979Snetchild */
57158979Snetchildstruct llentry {
58158979Snetchild	LIST_ENTRY(llentry)	 lle_next;
59158979Snetchild	struct rwlock		 lle_lock;
60158979Snetchild	struct lltable		 *lle_tbl;
61158979Snetchild	struct llentries	 *lle_head;
62158979Snetchild	void			(*lle_free)(struct lltable *, struct llentry *);
63158979Snetchild	struct mbuf		 *la_hold;
64158979Snetchild	int			 la_numheld;  /* # of packets currently held */
65158979Snetchild	time_t			 la_expire;
66158979Snetchild	uint16_t		 la_flags;
67158979Snetchild	uint16_t		 la_asked;
68158979Snetchild	uint16_t		 la_preempt;
69158979Snetchild	uint16_t		 ln_byhint;
70158979Snetchild	int16_t			 ln_state;	/* IPv6 has ND6_LLINFO_NOSTATE == -2 */
71158979Snetchild	uint16_t		 ln_router;
72158979Snetchild	time_t			 ln_ntick;
73158979Snetchild	int			 lle_refcnt;
74158979Snetchild
75158979Snetchild	union {
76158979Snetchild		uint64_t	mac_aligned;
77158979Snetchild		uint16_t	mac16[3];
78158979Snetchild#ifdef OFED
79158979Snetchild		uint8_t		mac8[20];	/* IB needs 20 bytes. */
80158979Snetchild#endif
81158979Snetchild	} ll_addr;
82158979Snetchild
83158979Snetchild	/* XXX af-private? */
84158979Snetchild	union {
85158979Snetchild		struct callout	ln_timer_ch;
86158979Snetchild		struct callout  la_timer;
87158979Snetchild	} lle_timer;
88158979Snetchild	/* NB: struct sockaddr must immediately follow */
89158979Snetchild};
90158979Snetchild
91158979Snetchild#define	LLE_WLOCK(lle)		rw_wlock(&(lle)->lle_lock)
92158979Snetchild#define	LLE_RLOCK(lle)		rw_rlock(&(lle)->lle_lock)
93158979Snetchild#define	LLE_WUNLOCK(lle)	rw_wunlock(&(lle)->lle_lock)
94158979Snetchild#define	LLE_RUNLOCK(lle)	rw_runlock(&(lle)->lle_lock)
95158979Snetchild#define	LLE_DOWNGRADE(lle)	rw_downgrade(&(lle)->lle_lock)
96158979Snetchild#define	LLE_TRY_UPGRADE(lle)	rw_try_upgrade(&(lle)->lle_lock)
97158979Snetchild#define	LLE_LOCK_INIT(lle)	rw_init_flags(&(lle)->lle_lock, "lle", RW_DUPOK)
98158979Snetchild#define	LLE_LOCK_DESTROY(lle)	rw_destroy(&(lle)->lle_lock)
99158979Snetchild#define	LLE_WLOCK_ASSERT(lle)	rw_assert(&(lle)->lle_lock, RA_WLOCKED)
100158979Snetchild
101158979Snetchild#define LLE_IS_VALID(lle)	(((lle) != NULL) && ((lle) != (void *)-1))
102158979Snetchild
103158979Snetchild#define	LLE_ADDREF(lle) do {					\
104158979Snetchild	LLE_WLOCK_ASSERT(lle);					\
105158979Snetchild	KASSERT((lle)->lle_refcnt >= 0,				\
106158979Snetchild	    ("negative refcnt %d on lle %p",			\
107158979Snetchild	    (lle)->lle_refcnt, (lle)));				\
108158979Snetchild	(lle)->lle_refcnt++;					\
109158979Snetchild} while (0)
110158979Snetchild
111158979Snetchild#define	LLE_REMREF(lle)	do {					\
112158979Snetchild	LLE_WLOCK_ASSERT(lle);					\
113158979Snetchild	KASSERT((lle)->lle_refcnt > 0,				\
114158979Snetchild	    ("bogus refcnt %d on lle %p",			\
115158979Snetchild	    (lle)->lle_refcnt, (lle)));				\
116158979Snetchild	(lle)->lle_refcnt--;					\
117158979Snetchild} while (0)
118158979Snetchild
119158979Snetchild#define	LLE_FREE_LOCKED(lle) do {				\
120158979Snetchild	if ((lle)->lle_refcnt == 1)				\
121158979Snetchild		(lle)->lle_free((lle)->lle_tbl, (lle));		\
122158979Snetchild	else {							\
123158979Snetchild		LLE_REMREF(lle);				\
124158979Snetchild		LLE_WUNLOCK(lle);				\
125158979Snetchild	}							\
126158979Snetchild	/* guard against invalid refs */			\
127158979Snetchild	(lle) = NULL;						\
128158979Snetchild} while (0)
129158979Snetchild
130158979Snetchild#define	LLE_FREE(lle) do {					\
131158979Snetchild	LLE_WLOCK(lle);						\
132158979Snetchild	LLE_FREE_LOCKED(lle);					\
133158979Snetchild} while (0)
134158979Snetchild
135158979Snetchild
136158979Snetchild#define	ln_timer_ch	lle_timer.ln_timer_ch
137158979Snetchild#define	la_timer	lle_timer.la_timer
138158979Snetchild
139158979Snetchild/* XXX bad name */
140158979Snetchild#define	L3_ADDR(lle)	((struct sockaddr *)(&lle[1]))
141158979Snetchild#define	L3_ADDR_LEN(lle)	(((struct sockaddr *)(&lle[1]))->sa_len)
142158979Snetchild
143158979Snetchild#ifndef LLTBL_HASHTBL_SIZE
144158979Snetchild#define	LLTBL_HASHTBL_SIZE	32	/* default 32 ? */
145158979Snetchild#endif
146158979Snetchild
147158979Snetchild#ifndef LLTBL_HASHMASK
148158979Snetchild#define	LLTBL_HASHMASK	(LLTBL_HASHTBL_SIZE - 1)
149158979Snetchild#endif
150158979Snetchild
151158979Snetchildstruct lltable {
152158979Snetchild	SLIST_ENTRY(lltable)	llt_link;
153158979Snetchild	struct llentries	lle_head[LLTBL_HASHTBL_SIZE];
154158979Snetchild	int			llt_af;
155158979Snetchild	struct ifnet		*llt_ifp;
156158979Snetchild
157158979Snetchild	void			(*llt_prefix_free)(struct lltable *,
158158979Snetchild				    const struct sockaddr *prefix,
159158979Snetchild				    const struct sockaddr *mask,
160158979Snetchild				    u_int flags);
161158979Snetchild	struct llentry *	(*llt_lookup)(struct lltable *, u_int flags,
162158979Snetchild				    const struct sockaddr *l3addr);
163158979Snetchild	int			(*llt_dump)(struct lltable *,
164158979Snetchild				    struct sysctl_req *);
165158979Snetchild};
166158979SnetchildMALLOC_DECLARE(M_LLTABLE);
167158979Snetchild
168158979Snetchild/*
169158979Snetchild * flags to be passed to arplookup.
170158979Snetchild */
171158979Snetchild#define	LLE_DELETED	0x0001	/* entry must be deleted */
172158979Snetchild#define	LLE_STATIC	0x0002	/* entry is static */
173158979Snetchild#define	LLE_IFADDR	0x0004	/* entry is interface addr */
174158979Snetchild#define	LLE_VALID	0x0008	/* ll_addr is valid */
175158979Snetchild#define	LLE_PROXY	0x0010	/* proxy entry ??? */
176158979Snetchild#define	LLE_PUB		0x0020	/* publish entry ??? */
177158979Snetchild#define	LLE_LINKED	0x0040	/* linked to lookup structure */
178158979Snetchild#define	LLE_EXCLUSIVE	0x2000	/* return lle xlocked  */
179158979Snetchild#define	LLE_DELETE	0x4000	/* delete on a lookup - match LLE_IFADDR */
180158979Snetchild#define	LLE_CREATE	0x8000	/* create on a lookup miss */
181158979Snetchild
182158979Snetchild#define LLATBL_HASH(key, mask) \
183158979Snetchild	(((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
184158979Snetchild
185158979Snetchildstruct lltable *lltable_init(struct ifnet *, int);
186158979Snetchildvoid		lltable_free(struct lltable *);
187158979Snetchildvoid		lltable_prefix_free(int, struct sockaddr *,
188158979Snetchild		    struct sockaddr *, u_int);
189158979Snetchild#if 0
190158979Snetchildvoid		lltable_drain(int);
191158979Snetchild#endif
192158979Snetchildint		lltable_sysctl_dumparp(int, struct sysctl_req *);
193158979Snetchild
194158979Snetchildsize_t		llentry_free(struct llentry *);
195158979Snetchildstruct llentry  *llentry_alloc(struct ifnet *, struct lltable *,
196158979Snetchild		    struct sockaddr_storage *);
197158979Snetchild
198158979Snetchild/*
199158979Snetchild * Generic link layer address lookup function.
200158979Snetchild */
201158979Snetchildstatic __inline struct llentry *
202158979Snetchildlla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
203158979Snetchild{
204158979Snetchild	return llt->llt_lookup(llt, flags, l3addr);
205158979Snetchild}
206158979Snetchild
207158979Snetchildint		lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);
208158979Snetchild#endif  /* _NET_IF_LLATBL_H_ */
209158979Snetchild