The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/if_llatbl.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: if_llatbl.h,v 1.19 2022/11/19 08:00:51 yamt Exp $      */
    2 /*
    3  * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
    4  * Copyright (c) 2004-2008 Qing Li. All rights reserved.
    5  * Copyright (c) 2008 Kip Macy. All rights reserved.
    6  * Copyright (c) 2015 The NetBSD Foundation, Inc.
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 #include <sys/cdefs.h>
   31 
   32 #ifndef _NET_IF_LLATBL_H_
   33 #define _NET_IF_LLATBL_H_
   34 
   35 #if defined(_KERNEL_OPT)
   36 #include "opt_gateway.h"
   37 #include "opt_mbuftrace.h"
   38 #endif
   39 
   40 #include <sys/rwlock.h>
   41 #include <sys/syslog.h>
   42 
   43 #include <netinet/in.h>
   44 
   45 struct ifnet;
   46 struct sysctl_req;
   47 struct rt_msghdr;
   48 struct rt_addrinfo;
   49 struct rt_walkarg;
   50 
   51 struct llentry;
   52 LIST_HEAD(llentries, llentry);
   53 
   54 extern krwlock_t lltable_rwlock;
   55 #define LLTABLE_RLOCK()         rw_enter(&lltable_rwlock, RW_READER)
   56 #define LLTABLE_RUNLOCK()       rw_exit(&lltable_rwlock)
   57 #define LLTABLE_WLOCK()         rw_enter(&lltable_rwlock, RW_WRITER)
   58 #define LLTABLE_WUNLOCK()       rw_exit(&lltable_rwlock)
   59 #define LLTABLE_LOCK_ASSERT()   KASSERT(rw_lock_held(&lltable_rwlock))
   60 
   61 /*
   62  * Code referencing llentry must at least hold
   63  * a shared lock
   64  */
   65 struct llentry {
   66         LIST_ENTRY(llentry)      lle_next;
   67         union l3addr {
   68                 struct in_addr  addr4;
   69                 struct in6_addr addr6;
   70         } r_l3addr;
   71         union {
   72                 uint64_t        mac_aligned;
   73                 uint16_t        mac16[3];
   74                 uint8_t         mac8[20];       /* IB needs 20 bytes. */
   75         } ll_addr;
   76         uint32_t                spare0;
   77         uint64_t                spare1;
   78 
   79         struct lltable           *lle_tbl;
   80         struct llentries         *lle_head;
   81         void                    (*lle_free)(struct llentry *);
   82         void                    (*lle_ll_free)(struct llentry *);
   83         struct mbuf              *la_hold;
   84         int                      la_numheld;  /* # of packets currently held */
   85         time_t                   la_expire;
   86         uint16_t                 la_flags;
   87         uint16_t                 la_asked;
   88         uint16_t                 la_preempt;
   89         uint16_t                 ln_byhint;
   90         int16_t                  ln_state;      /* ND_LLINFO_NOSTATE == -2 */
   91         uint16_t                 ln_router;
   92         time_t                   ln_ntick;
   93         int                      lle_refcnt;
   94 
   95         LIST_ENTRY(llentry)     lle_chain;      /* chain of deleted items */
   96         struct callout          lle_timer;
   97         krwlock_t               lle_lock;
   98 
   99 #ifdef __NetBSD__
  100 #define la_timer        lle_timer
  101 #define ln_timer_ch     lle_timer
  102 #define ln_expire       la_expire
  103 #define ln_asked        la_asked
  104 #define ln_hold         la_hold
  105         void                    *la_opaque;     /* For tokenring */
  106 #endif
  107 };
  108 
  109 
  110 #if 0
  111 #define LLE_LOCK_TRACE(t, lle)  log(LOG_DEBUG, \
  112                                     "%s:%d: LOCK(" #t "): lle=%p\n", \
  113                                     __func__, __LINE__, (lle))
  114 #else
  115 #define LLE_LOCK_TRACE(t, lle)  do {} while (0)
  116 #endif
  117 
  118 #define LLE_WLOCK(lle)          do { \
  119                                         LLE_LOCK_TRACE(WL, (lle)); \
  120                                         rw_enter(&(lle)->lle_lock, RW_WRITER); \
  121                                 } while (0)
  122 #define LLE_RLOCK(lle)          do { \
  123                                         LLE_LOCK_TRACE(RL, (lle)); \
  124                                         rw_enter(&(lle)->lle_lock, RW_READER); \
  125                                 } while (0)
  126 #define LLE_WUNLOCK(lle)        do { \
  127                                         LLE_LOCK_TRACE(WU, (lle)); \
  128                                         rw_exit(&(lle)->lle_lock); \
  129                                 } while (0)
  130 #define LLE_RUNLOCK(lle)        do { \
  131                                         LLE_LOCK_TRACE(RU, (lle)); \
  132                                         rw_exit(&(lle)->lle_lock); \
  133                                 } while (0)
  134 #define LLE_DOWNGRADE(lle)      rw_downgrade(&(lle)->lle_lock)
  135 #define LLE_TRY_UPGRADE(lle)    rw_tryupgrade(&(lle)->lle_lock)
  136 #ifdef __FreeBSD__
  137 #define LLE_LOCK_INIT(lle)      rw_init_flags(&(lle)->lle_lock, "lle", RW_DUPOK)
  138 #else /* XXX */
  139 #define LLE_LOCK_INIT(lle)      rw_init(&(lle)->lle_lock)
  140 #endif
  141 #define LLE_LOCK_DESTROY(lle)   rw_destroy(&(lle)->lle_lock)
  142 #define LLE_WLOCK_ASSERT(lle)   KASSERT(rw_write_held(&(lle)->lle_lock))
  143 
  144 #define LLE_IS_VALID(lle)       (((lle) != NULL) && ((lle) != (void *)-1))
  145 
  146 #if 0
  147 #define LLE_REF_TRACE(t, lle, n) \
  148         log(LOG_DEBUG, "%s:%d: %p REF(" #t "): refcnt=%d\n", \
  149             __func__, __LINE__, (lle), (n))
  150 #else
  151 #define LLE_REF_TRACE(t, lle, n)        do {} while (0)
  152 #endif
  153 
  154 #define LLE_ADDREF(lle) do {                                    \
  155         LLE_WLOCK_ASSERT(lle);                                  \
  156         LLE_REF_TRACE(ADD, (lle), (lle)->lle_refcnt);           \
  157         KASSERTMSG((lle)->lle_refcnt >= 0,                      \
  158             "negative refcnt %d on lle %p",                     \
  159             (lle)->lle_refcnt, (lle));                          \
  160         (lle)->lle_refcnt++;                                    \
  161 } while (0)
  162 
  163 #define LLE_REMREF(lle) do {                                    \
  164         LLE_WLOCK_ASSERT(lle);                                  \
  165         LLE_REF_TRACE(REM, (lle), (lle)->lle_refcnt);           \
  166         KASSERTMSG((lle)->lle_refcnt > 0,                       \
  167             "bogus refcnt %d on lle %p",                        \
  168             (lle)->lle_refcnt, (lle));                          \
  169         (lle)->lle_refcnt--;                                    \
  170         if ((lle)->lle_refcnt == 0)                             \
  171                 LLE_REF_TRACE(ZERO, (lle), (lle)->lle_refcnt);  \
  172 } while (0)
  173 
  174 #define LLE_FREE_LOCKED(lle) do {                               \
  175         if ((lle)->lle_refcnt == 1) {                           \
  176                 if ((lle)->lle_ll_free != NULL)                 \
  177                         (lle)->lle_ll_free(lle);                \
  178                 (lle)->lle_free(lle);                           \
  179         } else {                                                \
  180                 LLE_REMREF(lle);                                \
  181                 LLE_WUNLOCK(lle);                               \
  182         }                                                       \
  183         /* guard against invalid refs */                        \
  184         (lle) = NULL;                                           \
  185 } while (0)
  186 
  187 #define LLE_FREE(lle) do {                                      \
  188         LLE_WLOCK(lle);                                         \
  189         LLE_FREE_LOCKED(lle);                                   \
  190 } while (0)
  191 
  192 
  193 typedef struct llentry *(llt_lookup_t)(struct lltable *, u_int flags,
  194     const struct sockaddr *l3addr);
  195 typedef struct llentry *(llt_create_t)(struct lltable *, u_int flags,
  196     const struct sockaddr *l3addr, const struct rtentry *);
  197 typedef int (llt_delete_t)(struct lltable *, u_int flags,
  198     const struct sockaddr *l3addr);
  199 typedef void (llt_prefix_free_t)(struct lltable *,
  200     const struct sockaddr *prefix, const struct sockaddr *mask, u_int flags);
  201 typedef int (llt_dump_entry_t)(struct lltable *, struct llentry *,
  202     struct rt_walkarg *);
  203 typedef uint32_t (llt_hash_t)(const struct llentry *, uint32_t);
  204 typedef int (llt_match_prefix_t)(const struct sockaddr *,
  205     const struct sockaddr *, u_int, struct llentry *);
  206 typedef void (llt_free_entry_t)(struct lltable *, struct llentry *);
  207 typedef void (llt_fill_sa_entry_t)(const struct llentry *, struct sockaddr *);
  208 typedef void (llt_free_tbl_t)(struct lltable *);
  209 typedef void (llt_link_entry_t)(struct lltable *, struct llentry *);
  210 typedef void (llt_unlink_entry_t)(struct llentry *);
  211 
  212 typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *);
  213 typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *);
  214 
  215 struct lltable {
  216         SLIST_ENTRY(lltable)    llt_link;
  217         int                     llt_af;
  218         int                     llt_hsize;
  219         struct llentries        *lle_head;
  220         unsigned int            llt_lle_count;
  221         struct ifnet            *llt_ifp;
  222 
  223         llt_lookup_t            *llt_lookup;
  224         llt_create_t            *llt_create;
  225         llt_delete_t            *llt_delete;
  226         llt_prefix_free_t       *llt_prefix_free;
  227         llt_dump_entry_t        *llt_dump_entry;
  228         llt_hash_t              *llt_hash;
  229         llt_match_prefix_t      *llt_match_prefix;
  230         llt_free_entry_t        *llt_free_entry;
  231         llt_foreach_entry_t     *llt_foreach_entry;
  232         llt_link_entry_t        *llt_link_entry;
  233         llt_unlink_entry_t      *llt_unlink_entry;
  234         llt_fill_sa_entry_t     *llt_fill_sa_entry;
  235         llt_free_tbl_t          *llt_free_tbl;
  236 #ifdef MBUFTRACE
  237         struct mowner           *llt_mowner;
  238 #endif
  239 };
  240 
  241 MALLOC_DECLARE(M_LLTABLE);
  242 
  243 /*
  244  * LLentry flags
  245  */
  246 #define LLE_DELETED     0x0001  /* entry must be deleted */
  247 #define LLE_STATIC      0x0002  /* entry is static */
  248 #define LLE_IFADDR      0x0004  /* entry is interface addr */
  249 #define LLE_VALID       0x0008  /* ll_addr is valid */
  250 #define LLE_PUB         0x0020  /* publish entry ??? */
  251 #define LLE_LINKED      0x0040  /* linked to lookup structure */
  252 /* LLE request flags */
  253 #define LLE_EXCLUSIVE   0x2000  /* return lle xlocked  */
  254 
  255 #define LLATBL_HASH(key, mask) \
  256         (((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
  257 
  258 void lltableinit(void);
  259 
  260 struct lltable *lltable_allocate_htbl(uint32_t hsize);
  261 void            lltable_free(struct lltable *);
  262 void            lltable_link(struct lltable *llt);
  263 void            lltable_prefix_free(const int, const struct sockaddr *,
  264                     const struct sockaddr *, const u_int);
  265 void            lltable_drain(int);
  266 void            lltable_purge_entries(struct lltable *);
  267 int             lltable_sysctl_dump(int, struct rt_walkarg *);
  268 int             lltable_dump_entry(struct lltable *, struct llentry *,
  269                     struct rt_walkarg *, struct sockaddr *);
  270 
  271 size_t          llentry_free(struct llentry *);
  272 struct llentry  *llentry_alloc(struct ifnet *, struct lltable *,
  273                     struct sockaddr_storage *);
  274 
  275 struct llentry  *llentry_pool_get(int);
  276 void            llentry_pool_put(struct llentry *);
  277 
  278 /* helper functions */
  279 size_t lltable_drop_entry_queue(struct llentry *);
  280 
  281 struct llentry *lltable_create_lle(struct lltable *llt, u_int flags,
  282     const void *paddr);
  283 void lltable_link_entry(struct lltable *llt, struct llentry *lle);
  284 void lltable_unlink_entry(struct lltable *llt, struct llentry *lle);
  285 void lltable_free_entry(struct lltable *llt, struct llentry *lle);
  286 void lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa);
  287 struct ifnet *lltable_get_ifp(const struct lltable *llt);
  288 int lltable_get_af(const struct lltable *llt);
  289 
  290 static __inline unsigned int
  291 lltable_get_entry_count(struct lltable *llt)
  292 {
  293         return llt->llt_lle_count;
  294 }
  295 
  296 int lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f,
  297     void *farg);
  298 /*
  299  * Generic link layer address lookup function.
  300  */
  301 static __inline struct llentry *
  302 lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
  303 {
  304 
  305         return (llt->llt_lookup(llt, flags, l3addr));
  306 }
  307 
  308 static __inline struct llentry *
  309 lla_create(struct lltable *llt, u_int flags, const struct sockaddr *l3addr,
  310     const struct rtentry *rt)
  311 {
  312 
  313         return (llt->llt_create(llt, flags, l3addr, rt));
  314 }
  315 
  316 static __inline int
  317 lla_delete(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
  318 {
  319 
  320         return (llt->llt_delete(llt, flags, l3addr));
  321 }
  322 
  323 
  324 int lla_rt_output(const u_char, const int, const time_t,
  325     struct rt_addrinfo *info, int);
  326 
  327 #endif  /* _NET_IF_LLATBL_H_ */

Cache object: be92819a094cf2b0630136002aae9bcd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.