[funini.com] -> [kei@sodan] -> Kernel Reading

root/include/net/neighbour.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. neigh_parms_net
  2. pneigh_net
  3. __neigh_parms_put
  4. neigh_parms_clone
  5. neigh_release
  6. neigh_clone
  7. neigh_confirm
  8. neigh_event_send
  9. neigh_hh_output
  10. __neigh_lookup
  11. __neigh_lookup_errno

#ifndef _NET_NEIGHBOUR_H
#define _NET_NEIGHBOUR_H

#include <linux/neighbour.h>

/*
 *      Generic neighbour manipulation
 *
 *      Authors:
 *      Pedro Roque             <roque@di.fc.ul.pt>
 *      Alexey Kuznetsov        <kuznet@ms2.inr.ac.ru>
 *
 *      Changes:
 *
 *      Harald Welte:           <laforge@gnumonks.org>
 *              - Add neighbour cache statistics like rtstat
 */

#include <asm/atomic.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/rcupdate.h>
#include <linux/seq_file.h>

#include <linux/err.h>
#include <linux/sysctl.h>
#include <net/rtnetlink.h>

/*
 * NUD stands for "neighbor unreachability detection"
 */

#define NUD_IN_TIMER    (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
#define NUD_VALID       (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
#define NUD_CONNECTED   (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)

struct neighbour;

struct neigh_parms
{
#ifdef CONFIG_NET_NS
        struct net *net;
#endif
        struct net_device *dev;
        struct neigh_parms *next;
        int     (*neigh_setup)(struct neighbour *);
        void    (*neigh_cleanup)(struct neighbour *);
        struct neigh_table *tbl;

        void    *sysctl_table;

        int dead;
        atomic_t refcnt;
        struct rcu_head rcu_head;

        int     base_reachable_time;
        int     retrans_time;
        int     gc_staletime;
        int     reachable_time;
        int     delay_probe_time;

        int     queue_len;
        int     ucast_probes;
        int     app_probes;
        int     mcast_probes;
        int     anycast_delay;
        int     proxy_delay;
        int     proxy_qlen;
        int     locktime;
};

struct neigh_statistics
{
        unsigned long allocs;           /* number of allocated neighs */
        unsigned long destroys;         /* number of destroyed neighs */
        unsigned long hash_grows;       /* number of hash resizes */

        unsigned long res_failed;       /* number of failed resolutions */

        unsigned long lookups;          /* number of lookups */
        unsigned long hits;             /* number of hits (among lookups) */

        unsigned long rcv_probes_mcast; /* number of received mcast ipv6 */
        unsigned long rcv_probes_ucast; /* number of received ucast ipv6 */

        unsigned long periodic_gc_runs; /* number of periodic GC runs */
        unsigned long forced_gc_runs;   /* number of forced GC runs */

        unsigned long unres_discards;   /* number of unresolved drops */
};

#define NEIGH_CACHE_STAT_INC(tbl, field)                                \
        do {                                                            \
                preempt_disable();                                      \
                (per_cpu_ptr((tbl)->stats, smp_processor_id())->field)++; \
                preempt_enable();                                       \
        } while (0)

struct neighbour
{
        struct neighbour        *next;
        struct neigh_table      *tbl;
        struct neigh_parms      *parms;
        struct net_device               *dev;
        unsigned long           used;
        unsigned long           confirmed;
        unsigned long           updated;
        __u8                    flags;
        __u8                    nud_state;
        __u8                    type;
        __u8                    dead;
        atomic_t                probes;
        rwlock_t                lock;
        unsigned char           ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
        struct hh_cache         *hh;
        atomic_t                refcnt;
        int                     (*output)(struct sk_buff *skb);
        struct sk_buff_head     arp_queue;
        struct timer_list       timer;
        struct neigh_ops        *ops;
        u8                      primary_key[0];
};

struct neigh_ops
{
        int                     family;
        void                    (*solicit)(struct neighbour *, struct sk_buff*);
        void                    (*error_report)(struct neighbour *, struct sk_buff*);
        int                     (*output)(struct sk_buff*);
        int                     (*connected_output)(struct sk_buff*);
        int                     (*hh_output)(struct sk_buff*);
        int                     (*queue_xmit)(struct sk_buff*);
};

struct pneigh_entry
{
        struct pneigh_entry     *next;
#ifdef CONFIG_NET_NS
        struct net              *net;
#endif
        struct net_device       *dev;
        u8                      flags;
        u8                      key[0];
};

/*
 *      neighbour table manipulation
 */


struct neigh_table
{
        struct neigh_table      *next;
        int                     family;
        int                     entry_size;
        int                     key_len;
        __u32                   (*hash)(const void *pkey, const struct net_device *);
        int                     (*constructor)(struct neighbour *);
        int                     (*pconstructor)(struct pneigh_entry *);
        void                    (*pdestructor)(struct pneigh_entry *);
        void                    (*proxy_redo)(struct sk_buff *skb);
        char                    *id;
        struct neigh_parms      parms;
        /* HACK. gc_* shoul follow parms without a gap! */
        int                     gc_interval;
        int                     gc_thresh1;
        int                     gc_thresh2;
        int                     gc_thresh3;
        unsigned long           last_flush;
        struct timer_list       gc_timer;
        struct timer_list       proxy_timer;
        struct sk_buff_head     proxy_queue;
        atomic_t                entries;
        rwlock_t                lock;
        unsigned long           last_rand;
        struct kmem_cache               *kmem_cachep;
        struct neigh_statistics *stats;
        struct neighbour        **hash_buckets;
        unsigned int            hash_mask;
        __u32                   hash_rnd;
        unsigned int            hash_chain_gc;
        struct pneigh_entry     **phash_buckets;
#ifdef CONFIG_PROC_FS
        struct proc_dir_entry   *pde;
#endif
};

/* flags for neigh_update() */
#define NEIGH_UPDATE_F_OVERRIDE                 0x00000001
#define NEIGH_UPDATE_F_WEAK_OVERRIDE            0x00000002
#define NEIGH_UPDATE_F_OVERRIDE_ISROUTER        0x00000004
#define NEIGH_UPDATE_F_ISROUTER                 0x40000000
#define NEIGH_UPDATE_F_ADMIN                    0x80000000

extern void                     neigh_table_init(struct neigh_table *tbl);
extern void                     neigh_table_init_no_netlink(struct neigh_table *tbl);
extern int                      neigh_table_clear(struct neigh_table *tbl);
extern struct neighbour *       neigh_lookup(struct neigh_table *tbl,
                                             const void *pkey,
                                             struct net_device *dev);
extern struct neighbour *       neigh_lookup_nodev(struct neigh_table *tbl,
                                                   struct net *net,
                                                   const void *pkey);
extern struct neighbour *       neigh_create(struct neigh_table *tbl,
                                             const void *pkey,
                                             struct net_device *dev);
extern void                     neigh_destroy(struct neighbour *neigh);
extern int                      __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
extern int                      neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, 
                                             u32 flags);
extern void                     neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
extern int                      neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
extern int                      neigh_resolve_output(struct sk_buff *skb);
extern int                      neigh_connected_output(struct sk_buff *skb);
extern int                      neigh_compat_output(struct sk_buff *skb);
extern struct neighbour         *neigh_event_ns(struct neigh_table *tbl,
                                                u8 *lladdr, void *saddr,
                                                struct net_device *dev);

extern struct neigh_parms       *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
extern void                     neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);

static inline
struct net                      *neigh_parms_net(const struct neigh_parms *parms)
{
#ifdef CONFIG_NET_NS
        return parms->net;
#else
        return &init_net;
#endif
}

extern unsigned long            neigh_rand_reach_time(unsigned long base);

extern void                     pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
                                               struct sk_buff *skb);
extern struct pneigh_entry      *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
extern struct pneigh_entry      *__pneigh_lookup(struct neigh_table *tbl,
                                                 struct net *net,
                                                 const void *key,
                                                 struct net_device *dev);
extern int                      pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);

static inline
struct net                      *pneigh_net(const struct pneigh_entry *pneigh)
{
#ifdef CONFIG_NET_NS
        return pneigh->net;
#else
        return &init_net;
#endif
}

extern void neigh_app_ns(struct neighbour *n);
extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));

struct neigh_seq_state {
        struct seq_net_private p;
        struct neigh_table *tbl;
        void *(*neigh_sub_iter)(struct neigh_seq_state *state,
                                struct neighbour *n, loff_t *pos);
        unsigned int bucket;
        unsigned int flags;
#define NEIGH_SEQ_NEIGH_ONLY    0x00000001
#define NEIGH_SEQ_IS_PNEIGH     0x00000002
#define NEIGH_SEQ_SKIP_NOARP    0x00000004
};
extern void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *, unsigned int);
extern void *neigh_seq_next(struct seq_file *, void *, loff_t *);
extern void neigh_seq_stop(struct seq_file *, void *);

extern int                      neigh_sysctl_register(struct net_device *dev, 
                                                      struct neigh_parms *p,
                                                      int p_id, int pdev_id,
                                                      char *p_name,
                                                      proc_handler *proc_handler,
                                                      ctl_handler *strategy);
extern void                     neigh_sysctl_unregister(struct neigh_parms *p);

static inline void __neigh_parms_put(struct neigh_parms *parms)
{
        atomic_dec(&parms->refcnt);
}

static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
{
        atomic_inc(&parms->refcnt);
        return parms;
}

/*
 *      Neighbour references
 */

static inline void neigh_release(struct neighbour *neigh)
{
        if (atomic_dec_and_test(&neigh->refcnt))
                neigh_destroy(neigh);
}

static inline struct neighbour * neigh_clone(struct neighbour *neigh)
{
        if (neigh)
                atomic_inc(&neigh->refcnt);
        return neigh;
}

#define neigh_hold(n)   atomic_inc(&(n)->refcnt)

static inline void neigh_confirm(struct neighbour *neigh)
{
        if (neigh)
                neigh->confirmed = jiffies;
}

static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
{
        neigh->used = jiffies;
        if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
                return __neigh_event_send(neigh, skb);
        return 0;
}

static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
{
        unsigned seq;
        int hh_len;

        do {
                int hh_alen;

                seq = read_seqbegin(&hh->hh_lock);
                hh_len = hh->hh_len;
                hh_alen = HH_DATA_ALIGN(hh_len);
                memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
        } while (read_seqretry(&hh->hh_lock, seq));

        skb_push(skb, hh_len);
        return hh->hh_output(skb);
}

static inline struct neighbour *
__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
{
        struct neighbour *n = neigh_lookup(tbl, pkey, dev);

        if (n || !creat)
                return n;

        n = neigh_create(tbl, pkey, dev);
        return IS_ERR(n) ? NULL : n;
}

static inline struct neighbour *
__neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
  struct net_device *dev)
{
        struct neighbour *n = neigh_lookup(tbl, pkey, dev);

        if (n)
                return n;

        return neigh_create(tbl, pkey, dev);
}

struct neighbour_cb {
        unsigned long sched_next;
        unsigned int flags;
};

#define LOCALLY_ENQUEUED 0x1

#define NEIGH_CB(skb)   ((struct neighbour_cb *)(skb)->cb)

#endif

/* [<][>][^][v][top][bottom][index][help] */

[funini.com] -> [kei@sodan] -> Kernel Reading