#define pr_fmt(fmt) …
#include <linux/slab.h>
#include <linux/kmemleak.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/netdevice.h>
#include <linux/proc_fs.h>
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#endif
#include <linux/times.h>
#include <net/net_namespace.h>
#include <net/neighbour.h>
#include <net/arp.h>
#include <net/dst.h>
#include <net/sock.h>
#include <net/netevent.h>
#include <net/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/random.h>
#include <linux/string.h>
#include <linux/log2.h>
#include <linux/inetdevice.h>
#include <net/addrconf.h>
#include <trace/events/neigh.h>
#define NEIGH_DEBUG …
#define neigh_dbg(level, fmt, ...) …
#define PNEIGH_HASHMASK …
static void neigh_timer_handler(struct timer_list *t);
static void __neigh_notify(struct neighbour *n, int type, int flags,
u32 pid);
static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid);
static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
struct net_device *dev);
#ifdef CONFIG_PROC_FS
static const struct seq_operations neigh_stat_seq_ops;
#endif
static int neigh_blackhole(struct neighbour *neigh, struct sk_buff *skb)
{ … }
static void neigh_cleanup_and_release(struct neighbour *neigh)
{ … }
unsigned long neigh_rand_reach_time(unsigned long base)
{ … }
EXPORT_SYMBOL(…);
static void neigh_mark_dead(struct neighbour *n)
{ … }
static void neigh_update_gc_list(struct neighbour *n)
{ … }
static void neigh_update_managed_list(struct neighbour *n)
{ … }
static void neigh_update_flags(struct neighbour *neigh, u32 flags, int *notify,
bool *gc_update, bool *managed_update)
{ … }
static bool neigh_del(struct neighbour *n, struct neighbour __rcu **np,
struct neigh_table *tbl)
{ … }
bool neigh_remove_one(struct neighbour *ndel, struct neigh_table *tbl)
{ … }
static int neigh_forced_gc(struct neigh_table *tbl)
{ … }
static void neigh_add_timer(struct neighbour *n, unsigned long when)
{ … }
static int neigh_del_timer(struct neighbour *n)
{ … }
static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
int family)
{ … }
static void neigh_parms_qlen_dec(struct net_device *dev, int family)
{ … }
static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net,
int family)
{ … }
static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev,
bool skip_perm)
{ … }
void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev)
{ … }
EXPORT_SYMBOL(…);
static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
bool skip_perm)
{ … }
int neigh_carrier_down(struct neigh_table *tbl, struct net_device *dev)
{ … }
EXPORT_SYMBOL(…);
int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
{ … }
EXPORT_SYMBOL(…);
static struct neighbour *neigh_alloc(struct neigh_table *tbl,
struct net_device *dev,
u32 flags, bool exempt_from_gc)
{ … }
static void neigh_get_hash_rnd(u32 *x)
{ … }
static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift)
{ … }
static void neigh_hash_free_rcu(struct rcu_head *head)
{ … }
static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl,
unsigned long new_shift)
{ … }
struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
struct net_device *dev)
{ … }
EXPORT_SYMBOL(…);
static struct neighbour *
___neigh_create(struct neigh_table *tbl, const void *pkey,
struct net_device *dev, u32 flags,
bool exempt_from_gc, bool want_ref)
{ … }
struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
struct net_device *dev, bool want_ref)
{ … }
EXPORT_SYMBOL(…);
static u32 pneigh_hash(const void *pkey, unsigned int key_len)
{ … }
static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n,
struct net *net,
const void *pkey,
unsigned int key_len,
struct net_device *dev)
{ … }
struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl,
struct net *net, const void *pkey, struct net_device *dev)
{ … }
EXPORT_SYMBOL_GPL(…);
struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
struct net *net, const void *pkey,
struct net_device *dev, int creat)
{ … }
EXPORT_SYMBOL(…);
int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
struct net_device *dev)
{ … }
static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
struct net_device *dev)
{ … }
static void neigh_parms_destroy(struct neigh_parms *parms);
static inline void neigh_parms_put(struct neigh_parms *parms)
{ … }
void neigh_destroy(struct neighbour *neigh)
{ … }
EXPORT_SYMBOL(…);
static void neigh_suspect(struct neighbour *neigh)
{ … }
static void neigh_connect(struct neighbour *neigh)
{ … }
static void neigh_periodic_work(struct work_struct *work)
{ … }
static __inline__ int neigh_max_probes(struct neighbour *n)
{ … }
static void neigh_invalidate(struct neighbour *neigh)
__releases(neigh->lock)
__acquires(neigh->lock)
{ … }
static void neigh_probe(struct neighbour *neigh)
__releases(neigh->lock)
{ … }
static void neigh_timer_handler(struct timer_list *t)
{ … }
int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb,
const bool immediate_ok)
{ … }
EXPORT_SYMBOL(…);
static void neigh_update_hhs(struct neighbour *neigh)
{ … }
static int __neigh_update(struct neighbour *neigh, const u8 *lladdr,
u8 new, u32 flags, u32 nlmsg_pid,
struct netlink_ext_ack *extack)
{ … }
int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
u32 flags, u32 nlmsg_pid)
{ … }
EXPORT_SYMBOL(…);
void __neigh_set_probe_once(struct neighbour *neigh)
{ … }
EXPORT_SYMBOL(…);
struct neighbour *neigh_event_ns(struct neigh_table *tbl,
u8 *lladdr, void *saddr,
struct net_device *dev)
{ … }
EXPORT_SYMBOL(…);
static void neigh_hh_init(struct neighbour *n)
{ … }
int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb)
{ … }
EXPORT_SYMBOL(…);
int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb)
{ … }
EXPORT_SYMBOL(…);
int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb)
{ … }
EXPORT_SYMBOL(…);
static void neigh_managed_work(struct work_struct *work)
{ … }
static void neigh_proxy_process(struct timer_list *t)
{ … }
static unsigned long neigh_proxy_delay(struct neigh_parms *p)
{ … }
void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
struct sk_buff *skb)
{ … }
EXPORT_SYMBOL(…);
static inline struct neigh_parms *lookup_neigh_parms(struct neigh_table *tbl,
struct net *net, int ifindex)
{ … }
struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
struct neigh_table *tbl)
{ … }
EXPORT_SYMBOL(…);
static void neigh_rcu_free_parms(struct rcu_head *head)
{ … }
void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
{ … }
EXPORT_SYMBOL(…);
static void neigh_parms_destroy(struct neigh_parms *parms)
{ … }
static struct lock_class_key neigh_table_proxy_queue_class;
static struct neigh_table __rcu *neigh_tables[NEIGH_NR_TABLES] __read_mostly;
void neigh_table_init(int index, struct neigh_table *tbl)
{ … }
EXPORT_SYMBOL(…);
int neigh_table_clear(int index, struct neigh_table *tbl)
{ … }
EXPORT_SYMBOL(…);
static struct neigh_table *neigh_find_table(int family)
{ … }
const struct nla_policy nda_policy[NDA_MAX+1] = …;
static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
{ … }
static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
u32 pid, u32 seq, int type, int flags)
{ … }
static int neightbl_fill_param_info(struct sk_buff *skb,
struct neigh_table *tbl,
struct neigh_parms *parms,
u32 pid, u32 seq, int type,
unsigned int flags)
{ … }
static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = …;
static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = …;
static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
static int neightbl_valid_dump_info(const struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh,
u32 pid, u32 seq, int type, unsigned int flags)
{ … }
static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
u32 pid, u32 seq, int type, unsigned int flags,
struct neigh_table *tbl)
{ … }
static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid)
{ … }
static bool neigh_master_filtered(struct net_device *dev, int master_idx)
{ … }
static bool neigh_ifindex_filtered(struct net_device *dev, int filter_idx)
{ … }
struct neigh_dump_filter { … };
static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
struct netlink_callback *cb,
struct neigh_dump_filter *filter)
{ … }
static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
struct netlink_callback *cb,
struct neigh_dump_filter *filter)
{ … }
static int neigh_valid_dump_req(const struct nlmsghdr *nlh,
bool strict_check,
struct neigh_dump_filter *filter,
struct netlink_ext_ack *extack)
{ … }
static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int neigh_valid_get_req(const struct nlmsghdr *nlh,
struct neigh_table **tbl,
void **dst, int *dev_idx, u8 *ndm_flags,
struct netlink_ext_ack *extack)
{ … }
static inline size_t neigh_nlmsg_size(void)
{ … }
static int neigh_get_reply(struct net *net, struct neighbour *neigh,
u32 pid, u32 seq)
{ … }
static inline size_t pneigh_nlmsg_size(void)
{ … }
static int pneigh_get_reply(struct net *net, struct pneigh_entry *neigh,
u32 pid, u32 seq, struct neigh_table *tbl)
{ … }
static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie)
{ … }
EXPORT_SYMBOL(…);
void __neigh_for_each_release(struct neigh_table *tbl,
int (*cb)(struct neighbour *))
{ … }
EXPORT_SYMBOL(…);
int neigh_xmit(int index, struct net_device *dev,
const void *addr, struct sk_buff *skb)
{ … }
EXPORT_SYMBOL(…);
#ifdef CONFIG_PROC_FS
static struct neighbour *neigh_get_first(struct seq_file *seq)
{ … }
static struct neighbour *neigh_get_next(struct seq_file *seq,
struct neighbour *n,
loff_t *pos)
{ … }
static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
{ … }
static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
{ … }
static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
struct pneigh_entry *pn,
loff_t *pos)
{ … }
static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos)
{ … }
static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
{ … }
void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
__acquires(tbl->lock)
__acquires(rcu)
{ … }
EXPORT_SYMBOL(…);
void *neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ … }
EXPORT_SYMBOL(…);
void neigh_seq_stop(struct seq_file *seq, void *v)
__releases(tbl->lock)
__releases(rcu)
{ … }
EXPORT_SYMBOL(…);
static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos)
{ … }
static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ … }
static void neigh_stat_seq_stop(struct seq_file *seq, void *v)
{ … }
static int neigh_stat_seq_show(struct seq_file *seq, void *v)
{ … }
static const struct seq_operations neigh_stat_seq_ops = …;
#endif
static void __neigh_notify(struct neighbour *n, int type, int flags,
u32 pid)
{ … }
void neigh_app_ns(struct neighbour *n)
{ … }
EXPORT_SYMBOL(…);
#ifdef CONFIG_SYSCTL
static int unres_qlen_max = …;
static int proc_unres_qlen(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p,
int index)
{ … }
static void neigh_proc_update(const struct ctl_table *ctl, int write)
{ … }
static int neigh_proc_dointvec_zero_intmax(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp,
loff_t *ppos)
{ … }
static int neigh_proc_dointvec_ms_jiffies_positive(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
int neigh_proc_dointvec(const struct ctl_table *ctl, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{ … }
EXPORT_SYMBOL(…);
int neigh_proc_dointvec_jiffies(const struct ctl_table *ctl, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{ … }
EXPORT_SYMBOL(…);
static int neigh_proc_dointvec_userhz_jiffies(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp,
loff_t *ppos)
{ … }
int neigh_proc_dointvec_ms_jiffies(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
EXPORT_SYMBOL(…);
static int neigh_proc_dointvec_unres_qlen(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp,
loff_t *ppos)
{ … }
static int neigh_proc_base_reachable_time(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp,
loff_t *ppos)
{ … }
#define NEIGH_PARMS_DATA_OFFSET(index) …
#define NEIGH_SYSCTL_ENTRY(attr, data_attr, name, mval, proc) …
#define NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(attr, name) …
#define NEIGH_SYSCTL_JIFFIES_ENTRY(attr, name) …
#define NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(attr, name) …
#define NEIGH_SYSCTL_MS_JIFFIES_POSITIVE_ENTRY(attr, name) …
#define NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(attr, data_attr, name) …
#define NEIGH_SYSCTL_UNRES_QLEN_REUSED_ENTRY(attr, data_attr, name) …
static struct neigh_sysctl_table { … } neigh_sysctl_template __read_mostly = …;
int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
proc_handler *handler)
{ … }
EXPORT_SYMBOL(…);
void neigh_sysctl_unregister(struct neigh_parms *p)
{ … }
EXPORT_SYMBOL(…);
#endif
static int __init neigh_init(void)
{ … }
subsys_initcall(neigh_init);