summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net/if_llatbl.h
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/net/if_llatbl.h')
-rw-r--r--freebsd/sys/net/if_llatbl.h147
1 files changed, 98 insertions, 49 deletions
diff --git a/freebsd/sys/net/if_llatbl.h b/freebsd/sys/net/if_llatbl.h
index 8ac72c4f..51de726a 100644
--- a/freebsd/sys/net/if_llatbl.h
+++ b/freebsd/sys/net/if_llatbl.h
@@ -30,8 +30,6 @@ __FBSDID("$FreeBSD$");
#ifndef _NET_IF_LLATBL_H_
#define _NET_IF_LLATBL_H_
-#include <rtems/bsd/local/opt_ofed.h>
-
#include <sys/_rwlock.h>
#include <netinet/in.h>
@@ -50,42 +48,44 @@ extern struct rwlock lltable_rwlock;
#define LLTABLE_WUNLOCK() rw_wunlock(&lltable_rwlock)
#define LLTABLE_LOCK_ASSERT() rw_assert(&lltable_rwlock, RA_LOCKED)
+#define LLE_MAX_LINKHDR 24 /* Full IB header */
/*
* Code referencing llentry must at least hold
* a shared lock
*/
struct llentry {
LIST_ENTRY(llentry) lle_next;
- struct rwlock lle_lock;
+ union {
+ struct in_addr addr4;
+ struct in6_addr addr6;
+ } r_l3addr;
+ char r_linkdata[LLE_MAX_LINKHDR]; /* L2 data */
+ uint8_t r_hdrlen; /* length for LL header */
+ uint8_t spare0[3];
+ uint16_t r_flags; /* LLE runtime flags */
+ uint16_t r_skip_req; /* feedback from fast path */
+
struct lltable *lle_tbl;
struct llentries *lle_head;
- void (*lle_free)(struct lltable *, struct llentry *);
+ void (*lle_free)(struct llentry *);
struct mbuf *la_hold;
int la_numheld; /* # of packets currently held */
time_t la_expire;
uint16_t la_flags;
uint16_t la_asked;
uint16_t la_preempt;
- uint16_t ln_byhint;
int16_t ln_state; /* IPv6 has ND6_LLINFO_NOSTATE == -2 */
uint16_t ln_router;
time_t ln_ntick;
+ time_t lle_remtime; /* Real time remaining */
+ time_t lle_hittime; /* Time when r_skip_req was unset */
int lle_refcnt;
+ char *ll_addr; /* link-layer address */
- union {
- uint64_t mac_aligned;
- uint16_t mac16[3];
-#ifdef OFED
- uint8_t mac8[20]; /* IB needs 20 bytes. */
-#endif
- } ll_addr;
-
- /* XXX af-private? */
- union {
- struct callout ln_timer_ch;
- struct callout la_timer;
- } lle_timer;
- /* NB: struct sockaddr must immediately follow */
+ LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
+ struct callout lle_timer;
+ struct rwlock lle_lock;
+ struct mtx req_mtx;
};
#define LLE_WLOCK(lle) rw_wlock(&(lle)->lle_lock)
@@ -98,6 +98,12 @@ struct llentry {
#define LLE_LOCK_DESTROY(lle) rw_destroy(&(lle)->lle_lock)
#define LLE_WLOCK_ASSERT(lle) rw_assert(&(lle)->lle_lock, RA_WLOCKED)
+#define LLE_REQ_INIT(lle) mtx_init(&(lle)->req_mtx, "lle req", \
+ NULL, MTX_DEF)
+#define LLE_REQ_DESTROY(lle) mtx_destroy(&(lle)->req_mtx)
+#define LLE_REQ_LOCK(lle) mtx_lock(&(lle)->req_mtx)
+#define LLE_REQ_UNLOCK(lle) mtx_unlock(&(lle)->req_mtx)
+
#define LLE_IS_VALID(lle) (((lle) != NULL) && ((lle) != (void *)-1))
#define LLE_ADDREF(lle) do { \
@@ -118,7 +124,7 @@ struct llentry {
#define LLE_FREE_LOCKED(lle) do { \
if ((lle)->lle_refcnt == 1) \
- (lle)->lle_free((lle)->lle_tbl, (lle)); \
+ (lle)->lle_free(lle); \
else { \
LLE_REMREF(lle); \
LLE_WUNLOCK(lle); \
@@ -132,58 +138,77 @@ struct llentry {
LLE_FREE_LOCKED(lle); \
} while (0)
+typedef struct llentry *(llt_lookup_t)(struct lltable *, u_int flags,
+ const struct sockaddr *l3addr);
+typedef struct llentry *(llt_alloc_t)(struct lltable *, u_int flags,
+ const struct sockaddr *l3addr);
+typedef void (llt_delete_t)(struct lltable *, struct llentry *);
+typedef void (llt_prefix_free_t)(struct lltable *,
+ const struct sockaddr *addr, const struct sockaddr *mask, u_int flags);
+typedef int (llt_dump_entry_t)(struct lltable *, struct llentry *,
+ struct sysctl_req *);
+typedef uint32_t (llt_hash_t)(const struct llentry *, uint32_t);
+typedef int (llt_match_prefix_t)(const struct sockaddr *,
+ const struct sockaddr *, u_int, struct llentry *);
+typedef void (llt_free_entry_t)(struct lltable *, struct llentry *);
+typedef void (llt_fill_sa_entry_t)(const struct llentry *, struct sockaddr *);
+typedef void (llt_free_tbl_t)(struct lltable *);
+typedef void (llt_link_entry_t)(struct lltable *, struct llentry *);
+typedef void (llt_unlink_entry_t)(struct llentry *);
-#define ln_timer_ch lle_timer.ln_timer_ch
-#define la_timer lle_timer.la_timer
-
-/* XXX bad name */
-#define L3_ADDR(lle) ((struct sockaddr *)(&lle[1]))
-#define L3_ADDR_LEN(lle) (((struct sockaddr *)(&lle[1]))->sa_len)
-
-#ifndef LLTBL_HASHTBL_SIZE
-#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */
-#endif
-
-#ifndef LLTBL_HASHMASK
-#define LLTBL_HASHMASK (LLTBL_HASHTBL_SIZE - 1)
-#endif
+typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *);
+typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *);
struct lltable {
SLIST_ENTRY(lltable) llt_link;
- struct llentries lle_head[LLTBL_HASHTBL_SIZE];
int llt_af;
+ int llt_hsize;
+ struct llentries *lle_head;
struct ifnet *llt_ifp;
- void (*llt_prefix_free)(struct lltable *,
- const struct sockaddr *prefix,
- const struct sockaddr *mask,
- u_int flags);
- struct llentry * (*llt_lookup)(struct lltable *, u_int flags,
- const struct sockaddr *l3addr);
- int (*llt_dump)(struct lltable *,
- struct sysctl_req *);
+ llt_lookup_t *llt_lookup;
+ llt_alloc_t *llt_alloc_entry;
+ llt_delete_t *llt_delete_entry;
+ llt_prefix_free_t *llt_prefix_free;
+ llt_dump_entry_t *llt_dump_entry;
+ llt_hash_t *llt_hash;
+ llt_match_prefix_t *llt_match_prefix;
+ llt_free_entry_t *llt_free_entry;
+ llt_foreach_entry_t *llt_foreach_entry;
+ llt_link_entry_t *llt_link_entry;
+ llt_unlink_entry_t *llt_unlink_entry;
+ llt_fill_sa_entry_t *llt_fill_sa_entry;
+ llt_free_tbl_t *llt_free_tbl;
};
+
MALLOC_DECLARE(M_LLTABLE);
/*
- * flags to be passed to arplookup.
+ * LLentry flags
*/
#define LLE_DELETED 0x0001 /* entry must be deleted */
#define LLE_STATIC 0x0002 /* entry is static */
#define LLE_IFADDR 0x0004 /* entry is interface addr */
#define LLE_VALID 0x0008 /* ll_addr is valid */
-#define LLE_PROXY 0x0010 /* proxy entry ??? */
+#define LLE_REDIRECT 0x0010 /* installed by redirect; has host rtentry */
#define LLE_PUB 0x0020 /* publish entry ??? */
#define LLE_LINKED 0x0040 /* linked to lookup structure */
+/* LLE request flags */
#define LLE_EXCLUSIVE 0x2000 /* return lle xlocked */
-#define LLE_DELETE 0x4000 /* delete on a lookup - match LLE_IFADDR */
-#define LLE_CREATE 0x8000 /* create on a lookup miss */
+#define LLE_UNLOCKED 0x4000 /* return lle unlocked */
+#define LLE_ADDRONLY 0x4000 /* return lladdr instead of full header */
+#define LLE_CREATE 0x8000 /* hint to avoid lle lookup */
+
+/* LLE flags used by fastpath code */
+#define RLLE_VALID 0x0001 /* entry is valid */
+#define RLLE_IFADDR LLE_IFADDR /* entry is ifaddr */
#define LLATBL_HASH(key, mask) \
(((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
-struct lltable *lltable_init(struct ifnet *, int);
+struct lltable *lltable_allocate_htbl(uint32_t hsize);
void lltable_free(struct lltable *);
+void lltable_link(struct lltable *llt);
void lltable_prefix_free(int, struct sockaddr *,
struct sockaddr *, u_int);
#if 0
@@ -195,13 +220,37 @@ size_t llentry_free(struct llentry *);
struct llentry *llentry_alloc(struct ifnet *, struct lltable *,
struct sockaddr_storage *);
+/* helper functions */
+size_t lltable_drop_entry_queue(struct llentry *);
+void lltable_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
+ const char *linkhdr, size_t linkhdrsize, int lladdr_off);
+int lltable_try_set_entry_addr(struct ifnet *ifp, struct llentry *lle,
+ const char *linkhdr, size_t linkhdrsize, int lladdr_off);
+
+int lltable_calc_llheader(struct ifnet *ifp, int family, char *lladdr,
+ char *buf, size_t *bufsize, int *lladdr_off);
+void lltable_update_ifaddr(struct lltable *llt);
+struct llentry *lltable_alloc_entry(struct lltable *llt, u_int flags,
+ const struct sockaddr *l4addr);
+void lltable_free_entry(struct lltable *llt, struct llentry *lle);
+int lltable_delete_addr(struct lltable *llt, u_int flags,
+ const struct sockaddr *l3addr);
+void lltable_link_entry(struct lltable *llt, struct llentry *lle);
+void lltable_unlink_entry(struct lltable *llt, struct llentry *lle);
+void lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa);
+struct ifnet *lltable_get_ifp(const struct lltable *llt);
+int lltable_get_af(const struct lltable *llt);
+
+int lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f,
+ void *farg);
/*
* Generic link layer address lookup function.
*/
static __inline struct llentry *
lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
{
- return llt->llt_lookup(llt, flags, l3addr);
+
+ return (llt->llt_lookup(llt, flags, l3addr));
}
int lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);