Skip to content

Commit

Permalink
Merge branch 'neigh'
Browse files Browse the repository at this point in the history
Jiri Pirko says:

====================
neigh: respect default parms values

This is a long standing regression. But since the patchset is bigger and
the regression happened in 2007, I'm proposing this to net-next instead.

Basically the problem is that if user wants to use /etc/sysctl.conf to specify
default values of neigh related params, he is not able to do that.

The reason is that the default values are copied to dev instance right after
netdev is registered. And that is way to early. The original behaviour
for ipv4 was that this happened after first address was assigned to device.
For ipv6 this was apparently from the very beginning.

So this patchset basically reverts the behaviour back to what it was in 2007 for
ipv4 and changes the behaviour for ipv6 so they are both the same.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 10, 2013
2 parents 65be629 + bba2489 commit 4e58879
Show file tree
Hide file tree
Showing 11 changed files with 414 additions and 272 deletions.
7 changes: 7 additions & 0 deletions include/linux/inetdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
return rtnl_dereference(dev->ip_ptr);
}

static inline struct neigh_parms *__in_dev_arp_parms_get_rcu(const struct net_device *dev)
{
struct in_device *in_dev = __in_dev_get_rcu(dev);

return in_dev ? in_dev->arp_parms : NULL;
}

void in_dev_finish_destroy(struct in_device *idev);

static inline void in_dev_put(struct in_device *idev)
Expand Down
7 changes: 7 additions & 0 deletions include/net/addrconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,13 @@ static inline struct inet6_dev *in6_dev_get(const struct net_device *dev)
return idev;
}

static inline struct neigh_parms *__in6_dev_nd_parms_get_rcu(const struct net_device *dev)
{
struct inet6_dev *idev = __in6_dev_get(dev);

return idev ? idev->nd_parms : NULL;
}

void in6_dev_finish_destroy(struct inet6_dev *idev);

static inline void in6_dev_put(struct inet6_dev *idev)
Expand Down
77 changes: 63 additions & 14 deletions include/net/neighbour.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/rcupdate.h>
#include <linux/seq_file.h>
#include <linux/bitmap.h>

#include <linux/err.h>
#include <linux/sysctl.h>
Expand All @@ -37,6 +38,32 @@

struct neighbour;

enum {
NEIGH_VAR_MCAST_PROBES,
NEIGH_VAR_UCAST_PROBES,
NEIGH_VAR_APP_PROBES,
NEIGH_VAR_RETRANS_TIME,
NEIGH_VAR_BASE_REACHABLE_TIME,
NEIGH_VAR_DELAY_PROBE_TIME,
NEIGH_VAR_GC_STALETIME,
NEIGH_VAR_QUEUE_LEN_BYTES,
NEIGH_VAR_PROXY_QLEN,
NEIGH_VAR_ANYCAST_DELAY,
NEIGH_VAR_PROXY_DELAY,
NEIGH_VAR_LOCKTIME,
#define NEIGH_VAR_DATA_MAX (NEIGH_VAR_LOCKTIME + 1)
/* Following are used as a second way to access one of the above */
NEIGH_VAR_QUEUE_LEN, /* same data as NEIGH_VAR_QUEUE_LEN_BYTES */
NEIGH_VAR_RETRANS_TIME_MS, /* same data as NEIGH_VAR_RETRANS_TIME */
NEIGH_VAR_BASE_REACHABLE_TIME_MS, /* same data as NEIGH_VAR_BASE_REACHABLE_TIME */
/* Following are used by "default" only */
NEIGH_VAR_GC_INTERVAL,
NEIGH_VAR_GC_THRESH1,
NEIGH_VAR_GC_THRESH2,
NEIGH_VAR_GC_THRESH3,
NEIGH_VAR_MAX
};

struct neigh_parms {
#ifdef CONFIG_NET_NS
struct net *net;
Expand All @@ -53,22 +80,30 @@ struct neigh_parms {
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_bytes;
int ucast_probes;
int app_probes;
int mcast_probes;
int anycast_delay;
int proxy_delay;
int proxy_qlen;
int locktime;
int data[NEIGH_VAR_DATA_MAX];
DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX);
};

static inline void neigh_var_set(struct neigh_parms *p, int index, int val)
{
set_bit(index, p->data_state);
p->data[index] = val;
}

#define NEIGH_VAR(p, attr) ((p)->data[NEIGH_VAR_ ## attr])
#define NEIGH_VAR_SET(p, attr, val) neigh_var_set(p, NEIGH_VAR_ ## attr, val)

static inline void neigh_parms_data_state_setall(struct neigh_parms *p)
{
bitmap_fill(p->data_state, NEIGH_VAR_DATA_MAX);
}

static inline void neigh_parms_data_state_cleanall(struct neigh_parms *p)
{
bitmap_zero(p->data_state, NEIGH_VAR_DATA_MAX);
}

struct neigh_statistics {
unsigned long allocs; /* number of allocated neighs */
unsigned long destroys; /* number of destroyed neighs */
Expand Down Expand Up @@ -180,6 +215,11 @@ struct neigh_table {
struct pneigh_entry **phash_buckets;
};

static inline int neigh_parms_family(struct neigh_parms *p)
{
return p->tbl->family;
}

#define NEIGH_PRIV_ALIGN sizeof(long long)
#define NEIGH_ENTRY_SIZE(size) ALIGN((size), NEIGH_PRIV_ALIGN)

Expand Down Expand Up @@ -274,8 +314,17 @@ void *neigh_seq_start(struct seq_file *, loff_t *, struct neigh_table *,
void *neigh_seq_next(struct seq_file *, void *, loff_t *);
void neigh_seq_stop(struct seq_file *, void *);

int neigh_proc_dointvec(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write,
void __user *buffer,
size_t *lenp, loff_t *ppos);
int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write,
void __user *buffer,
size_t *lenp, loff_t *ppos);

int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
char *p_name, proc_handler *proc_handler);
proc_handler *proc_handler);
void neigh_sysctl_unregister(struct neigh_parms *p);

static inline void __neigh_parms_put(struct neigh_parms *parms)
Expand Down
4 changes: 2 additions & 2 deletions net/802/hippi.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,14 @@ EXPORT_SYMBOL(hippi_mac_addr);
int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
{
/* Never send broadcast/multicast ARP messages */
p->mcast_probes = 0;
NEIGH_VAR_SET(p, MCAST_PROBES, 0);

/* In IPv6 unicast probes are valid even on NBMA,
* because they are encapsulated in normal IPv6 protocol.
* Should be a generic flag.
*/
if (p->tbl->family != AF_INET6)
p->ucast_probes = 0;
NEIGH_VAR_SET(p, UCAST_PROBES, 0);
return 0;
}
EXPORT_SYMBOL(hippi_neigh_setup_dev);
Expand Down
Loading

0 comments on commit 4e58879

Please sign in to comment.