Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95ae6b22 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

ipv4: ip_ptr cleanups



dev->ip_ptr is protected by rtnl and rcu.

Yet some places dont use appropriate primitives and/or locking rules.

Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9e0064a5
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -995,8 +995,10 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
static void
plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth)
{
	const struct in_device *in_dev = dev->ip_ptr;
	const struct in_device *in_dev;

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(dev);
	if (in_dev) {
		/* Any address will do - we take the first */
		const struct in_ifaddr *ifa = in_dev->ifa_list;
@@ -1006,6 +1008,7 @@ plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth)
			memcpy(eth->h_dest+2, &ifa->ifa_address, 4);
		}
	}
	rcu_read_unlock();
}

static int
@@ -1088,7 +1091,8 @@ plip_open(struct net_device *dev)
	   when the device address isn't identical to the address of a
	   received frame, the kernel incorrectly drops it).             */

	if ((in_dev=dev->ip_ptr) != NULL) {
	in_dev=__in_dev_get_rtnl(dev);
	if (in_dev) {
		/* Any address will do - we take the first. We already
		   have the first two bytes filled with 0xfc, from
		   plip_init_dev(). */
+7 −4
Original line number Diff line number Diff line
@@ -1504,22 +1504,25 @@ struct velocity_info {
 *	addresses on this chain then we use the first - multi-IP WOL is not
 *	supported.
 *
 *	CHECK ME: locking
 */

static inline int velocity_get_ip(struct velocity_info *vptr)
{
	struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr;
	struct in_device *in_dev;
	struct in_ifaddr *ifa;
	int res = -ENOENT;

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(vptr->dev);
	if (in_dev != NULL) {
		ifa = (struct in_ifaddr *) in_dev->ifa_list;
		if (ifa != NULL) {
			memcpy(vptr->ip_addr, &ifa->ifa_address, 4);
			return 0;
			res = 0;
		}
	}
	return -ENOENT;
	rcu_read_unlock();
	return res;
}

/**
+3 −1
Original line number Diff line number Diff line
@@ -191,7 +191,8 @@ static int cisco_rx(struct sk_buff *skb)

		switch (ntohl (cisco_data->type)) {
		case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
			in_dev = dev->ip_ptr;
			rcu_read_lock();
			in_dev = __in_dev_get_rcu(dev);
			addr = 0;
			mask = ~cpu_to_be32(0); /* is the mask correct? */

@@ -211,6 +212,7 @@ static int cisco_rx(struct sk_buff *skb)
				cisco_keepalive_send(dev, CISCO_ADDR_REPLY,
						     addr, mask);
			}
			rcu_read_unlock();
			dev_kfree_skb_any(skb);
			return NET_RX_SUCCESS;

+5 −9
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/rcupdate.h>
#include <linux/timer.h>
#include <linux/sysctl.h>
#include <linux/rtnetlink.h>

enum
{
@@ -198,14 +199,10 @@ static __inline__ int bad_mask(__be32 mask, __be32 addr)

static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev)
{
	struct in_device *in_dev = dev->ip_ptr;
	if (in_dev)
		in_dev = rcu_dereference(in_dev);
	return in_dev;
	return rcu_dereference(dev->ip_ptr);
}

static __inline__ struct in_device *
in_dev_get(const struct net_device *dev)
static inline struct in_device *in_dev_get(const struct net_device *dev)
{
	struct in_device *in_dev;

@@ -217,10 +214,9 @@ in_dev_get(const struct net_device *dev)
	return in_dev;
}

static __inline__ struct in_device *
__in_dev_get_rtnl(const struct net_device *dev)
static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
{
	return (struct in_device*)dev->ip_ptr;
	return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held());
}

extern void in_dev_finish_destroy(struct in_device *idev);
+1 −1
Original line number Diff line number Diff line
@@ -942,7 +942,7 @@ struct net_device {
	void			*dsa_ptr;	/* dsa specific data */
#endif
	void 			*atalk_ptr;	/* AppleTalk link 	*/
	void			*ip_ptr;	/* IPv4 specific data	*/
	struct in_device __rcu	*ip_ptr;	/* IPv4 specific data	*/
	void                    *dn_ptr;        /* DECnet specific data */
	void                    *ip6_ptr;       /* IPv6 specific data */
	void			*ec_ptr;	/* Econet specific data	*/
Loading