From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jiri Pirko Subject: Re: [patch net-next v2 4/5] neigh: restore old behaviour of default parms values Date: Tue, 10 Dec 2013 15:51:27 +0100 Message-ID: <20131210145127.GD2469@minipsycho.orion> References: <1386440817-7846-1-git-send-email-jiri@resnulli.us> <1386440817-7846-5-git-send-email-jiri@resnulli.us> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: "netdev@vger.kernel.org" To: Or Gerlitz Return-path: Received: from mail-ee0-f53.google.com ([74.125.83.53]:39488 "EHLO mail-ee0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753402Ab3LJOvc (ORCPT ); Tue, 10 Dec 2013 09:51:32 -0500 Received: by mail-ee0-f53.google.com with SMTP id b57so2252301eek.26 for ; Tue, 10 Dec 2013 06:51:30 -0800 (PST) Content-Disposition: inline In-Reply-To: Sender: netdev-owner@vger.kernel.org List-ID: Tue, Dec 10, 2013 at 03:09:05PM CET, or.gerlitz@gmail.com wrote: >On Sat, Dec 7, 2013 at 8:26 PM, Jiri Pirko wrote: >> Previously inet devices were only constructed when addresses are added. >> Therefore the default neigh parms values they get are the ones at the >> time of these operations. > >> >> Now that we're creating inet devices earlier, this changes the behaviour >> of default neigh parms values in an incompatible way (see bug #8519). >> >> This patch creates a compromise by setting the default values at the >> same point as before but only for those that have not been explicitly >> set by the user since the inet device's creation. >> >> Introduced by: >> commit 8030f54499925d073a88c09f30d5d844fb1b3190 >> Author: Herbert Xu >> Date: Thu Feb 22 01:53:47 2007 +0900 >> >> [IPV4] devinet: Register inetdev earlier. >> >> Signed-off-by: Jiri Pirko >> --- >> include/linux/inetdevice.h | 7 +++++ >> include/net/neighbour.h | 13 ++++++++ >> net/core/neighbour.c | 74 ++++++++++++++++++++++++++++++++++++++++++---- >> net/ipv4/devinet.c | 2 ++ >> net/ipv4/ipmr.c | 2 ++ >> 5 files changed, 92 insertions(+), 6 deletions(-) >> >> diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h >> index 0d678ae..ae174ca 100644 >> --- a/include/linux/inetdevice.h >> +++ b/include/linux/inetdevice.h >> @@ -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) >> diff --git a/include/net/neighbour.h b/include/net/neighbour.h >> index 95615c9..41b1ce6 100644 >> --- a/include/net/neighbour.h >> +++ b/include/net/neighbour.h >> @@ -21,6 +21,7 @@ >> #include >> #include >> #include >> +#include >> >> #include >> #include >> @@ -81,16 +82,28 @@ struct neigh_parms { >> >> int reachable_time; >> 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 */ >> diff --git a/net/core/neighbour.c b/net/core/neighbour.c >> index 65ead08..c4a7879 100644 >> --- a/net/core/neighbour.c >> +++ b/net/core/neighbour.c >> @@ -38,6 +38,7 @@ >> #include >> #include >> #include >> +#include >> >> #define DEBUG >> #define NEIGH_DEBUG 1 >> @@ -1464,6 +1465,8 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, >> p->next = tbl->parms.next; >> tbl->parms.next = p; >> write_unlock_bh(&tbl->lock); >> + >> + neigh_parms_data_state_cleanall(p); >> } >> return p; >> } >> @@ -2813,22 +2816,68 @@ static int proc_unres_qlen(struct ctl_table *ctl, int write, >> return ret; >> } >> >> +static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev, >> + int family) >> +{ >> + if (family == AF_INET) >> + return __in_dev_arp_parms_get_rcu(dev); >> + return NULL; >> +} >> + >> +static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p, >> + int index) >> +{ >> + struct net_device *dev; >> + int family = neigh_parms_family(p); >> + >> + rcu_read_lock(); >> + for_each_netdev_rcu(net, dev) { >> + struct neigh_parms *dst_p = >> + neigh_get_dev_parms_rcu(dev, family); >> + >> + if (dst_p && !test_bit(index, dst_p->data_state)) >> + dst_p->data[index] = p->data[index]; >> + } >> + rcu_read_unlock(); >> +} >> + >> +static void neigh_proc_update(struct ctl_table *ctl, int write) >> +{ >> + struct net_device *dev = ctl->extra1; >> + struct neigh_parms *p = ctl->extra2; >> + struct net *net = p->net; > > >Jiri, net-next build fails as of this line, if one doesn't have >CONFIG_NET_NS on their .config > >net/core/neighbour.c: In function neigh_proc_update: >net/core/neighbour.c:2853: error: struct neigh_parms has no member named net > >can you please fix? I already sent a fix: "[patch net-next] neighbour: always have struct net pointer in struct neigh_parms" sorry for any inconvenience. > >Or. > > > > >> + int index = (int *) ctl->data - p->data; >> + >> + if (!write) >> + return; >> + >> + set_bit(index, p->data_state); >> + if (!dev) /* NULL dev means this is default value */ >> + neigh_copy_dflt_parms(net, p, index); >> +} >> + >> static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write, >> void __user *buffer, >> size_t *lenp, loff_t *ppos) >> { >> struct ctl_table tmp = *ctl; >> + int ret; >> >> tmp.extra1 = &zero; >> tmp.extra2 = &int_max; >> >> - return proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); >> + ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); >> + neigh_proc_update(ctl, write); >> + return ret; >> } >> >> int neigh_proc_dointvec(struct ctl_table *ctl, int write, >> void __user *buffer, size_t *lenp, loff_t *ppos) >> { >> - return proc_dointvec(ctl, write, buffer, lenp, ppos); >> + int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); >> + >> + neigh_proc_update(ctl, write); >> + return ret; >> } >> EXPORT_SYMBOL(neigh_proc_dointvec); >> >> @@ -2836,7 +2885,10 @@ int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, >> void __user *buffer, >> size_t *lenp, loff_t *ppos) >> { >> - return proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); >> + int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); >> + >> + neigh_proc_update(ctl, write); >> + return ret; >> } >> EXPORT_SYMBOL(neigh_proc_dointvec_jiffies); >> >> @@ -2844,14 +2896,20 @@ static int neigh_proc_dointvec_userhz_jiffies(struct ctl_table *ctl, int write, >> void __user *buffer, >> size_t *lenp, loff_t *ppos) >> { >> - return proc_dointvec_userhz_jiffies(ctl, write, buffer, lenp, ppos); >> + int ret = proc_dointvec_userhz_jiffies(ctl, write, buffer, lenp, ppos); >> + >> + neigh_proc_update(ctl, write); >> + return ret; >> } >> >> int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write, >> void __user *buffer, >> size_t *lenp, loff_t *ppos) >> { >> - return proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos); >> + int ret = proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos); >> + >> + neigh_proc_update(ctl, write); >> + return ret; >> } >> EXPORT_SYMBOL(neigh_proc_dointvec_ms_jiffies); >> >> @@ -2859,7 +2917,10 @@ static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write, >> void __user *buffer, >> size_t *lenp, loff_t *ppos) >> { >> - return proc_unres_qlen(ctl, write, buffer, lenp, ppos); >> + int ret = proc_unres_qlen(ctl, write, buffer, lenp, ppos); >> + >> + neigh_proc_update(ctl, write); >> + return ret; >> } >> >> #define NEIGH_PARMS_DATA_OFFSET(index) \ >> @@ -2962,6 +3023,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, >> for (i = 0; i < ARRAY_SIZE(t->neigh_vars); i++) { >> t->neigh_vars[i].data += (long) p; >> t->neigh_vars[i].extra1 = dev; >> + t->neigh_vars[i].extra2 = p; >> } >> >> if (dev) { >> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c >> index e1c1953..43065be 100644 >> --- a/net/ipv4/devinet.c >> +++ b/net/ipv4/devinet.c >> @@ -500,6 +500,7 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) >> return -ENOBUFS; >> } >> ipv4_devconf_setall(in_dev); >> + neigh_parms_data_state_setall(in_dev->arp_parms); >> if (ifa->ifa_dev != in_dev) { >> WARN_ON(ifa->ifa_dev); >> in_dev_hold(in_dev); >> @@ -747,6 +748,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh, >> goto errout; >> >> ipv4_devconf_setall(in_dev); >> + neigh_parms_data_state_setall(in_dev->arp_parms); >> in_dev_hold(in_dev); >> >> if (tb[IFA_ADDRESS] == NULL) >> diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c >> index 62212c7..421a249 100644 >> --- a/net/ipv4/ipmr.c >> +++ b/net/ipv4/ipmr.c >> @@ -425,6 +425,7 @@ struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v) >> goto failure; >> >> ipv4_devconf_setall(in_dev); >> + neigh_parms_data_state_setall(in_dev->arp_parms); >> IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; >> >> if (dev_open(dev)) >> @@ -517,6 +518,7 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt) >> } >> >> ipv4_devconf_setall(in_dev); >> + neigh_parms_data_state_setall(in_dev->arp_parms); >> IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; >> rcu_read_unlock(); >> >> -- >> 1.8.3.1 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe netdev" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html