}
rcu_read_lock();
- in_dev = __in_dev_get(dev);
+ in_dev = rcu_dereference(__in_dev_get(dev));
if (in_dev == NULL) {
rcu_read_unlock();
return -EINVAL;
}
parms = in_dev->arp_parms;
- if (parms) {
- __neigh_parms_put(neigh->parms);
- neigh->parms = neigh_parms_clone(parms);
- }
+ __neigh_parms_put(neigh->parms);
+ neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
neigh->type = inet_addr_type(*(u32 *) neigh->primary_key);
if (neigh->type != RTN_UNICAST) return -EINVAL;
rcu_read_lock();
- in_dev = __in_dev_get(dev);
+ in_dev = rcu_dereference(__in_dev_get(dev));
if (!in_dev) {
rcu_read_unlock();
return -EINVAL;
}
parms = in_dev->arp_parms;
- if (parms) {
- __neigh_parms_put(neigh->parms);
- neigh->parms = neigh_parms_clone(parms);
- }
+ __neigh_parms_put(neigh->parms);
+ neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
neigh->ops = &clip_neigh_ops;
#include <linux/sysctl.h>
#include <linux/notifier.h>
#include <asm/uaccess.h>
+#include <asm/system.h>
#include <net/neighbour.h>
#include <net/dst.h>
#include <net/flow.h>
memset(dn_db, 0, sizeof(struct dn_dev));
memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
+ smp_wmb();
dev->dn_ptr = dn_db;
dn_db->dev = dev;
init_timer(&dn_db->timer);
struct neigh_parms *parms;
rcu_read_lock();
- dn_db = dev->dn_ptr;
+ dn_db = rcu_dereference(dev->dn_ptr);
if (dn_db == NULL) {
rcu_read_unlock();
return -EINVAL;
}
parms = dn_db->neigh_parms;
- if (parms) {
- __neigh_parms_put(neigh->parms);
- neigh->parms = neigh_parms_clone(parms);
+ if (!parms) {
+ rcu_read_unlock();
+ return -EINVAL;
}
+
+ __neigh_parms_put(neigh->parms);
+ neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
if (dn_db->use_long)
neigh->type = inet_addr_type(addr);
rcu_read_lock();
- in_dev = __in_dev_get(dev);
+ in_dev = rcu_dereference(__in_dev_get(dev));
if (in_dev == NULL) {
rcu_read_unlock();
return -EINVAL;
}
parms = in_dev->arp_parms;
- if (parms) {
- __neigh_parms_put(neigh->parms);
- neigh->parms = neigh_parms_clone(parms);
- }
+ __neigh_parms_put(neigh->parms);
+ neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
if (dev->hard_header == NULL) {
}
parms = in6_dev->nd_parms;
- if (parms) {
- __neigh_parms_put(neigh->parms);
- neigh->parms = neigh_parms_clone(parms);
- }
+ __neigh_parms_put(neigh->parms);
+ neigh->parms = neigh_parms_clone(parms);
rcu_read_unlock();
neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST;