diff options
Diffstat (limited to 'freebsd/sys/net/if_llatbl.h')
-rw-r--r-- | freebsd/sys/net/if_llatbl.h | 147 |
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 *); |