inetdevice.h 6.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
#ifndef _LINUX_INETDEVICE_H
#define _LINUX_INETDEVICE_H

#ifdef __KERNEL__

6
#include <linux/bitmap.h>
L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/timer.h>

struct ipv4_devconf
{
	void	*sysctl;
15
	int	data[__NET_IPV4_CONF_MAX - 1];
16
	DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
L
Linus Torvalds 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
};

extern struct ipv4_devconf ipv4_devconf;

struct in_device
{
	struct net_device	*dev;
	atomic_t		refcnt;
	int			dead;
	struct in_ifaddr	*ifa_list;	/* IP ifaddr chain		*/
	rwlock_t		mc_list_lock;
	struct ip_mc_list	*mc_list;	/* IP multicast filter chain    */
	spinlock_t		mc_tomb_lock;
	struct ip_mc_list	*mc_tomb;
	unsigned long		mr_v1_seen;
	unsigned long		mr_v2_seen;
	unsigned long		mr_maxdelay;
	unsigned char		mr_qrv;
	unsigned char		mr_gq_running;
	unsigned char		mr_ifc_count;
	struct timer_list	mr_gq_timer;	/* general query timer */
	struct timer_list	mr_ifc_timer;	/* interface change timer */

	struct neigh_parms	*arp_parms;
	struct ipv4_devconf	cnf;
	struct rcu_head		rcu_head;
};

45 46 47 48 49 50 51 52 53 54 55 56 57
#define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
#define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr)

static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
{
	index--;
	return in_dev->cnf.data[index];
}

static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
				    int val)
{
	index--;
58
	set_bit(index, in_dev->cnf.state);
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
	in_dev->cnf.data[index] = val;
}

#define IN_DEV_CONF_GET(in_dev, attr) \
	ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr)
#define IN_DEV_CONF_SET(in_dev, attr, val) \
	ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val))

#define IN_DEV_ANDCONF(in_dev, attr) \
	(IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
#define IN_DEV_ORCONF(in_dev, attr) \
	(IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr))
#define IN_DEV_MAXCONF(in_dev, attr) \
	(max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr)))

#define IN_DEV_FORWARD(in_dev)		IN_DEV_CONF_GET((in_dev), FORWARDING)
#define IN_DEV_MFORWARD(in_dev)		(IPV4_DEVCONF_ALL(MC_FORWARDING) && \
					 IPV4_DEVCONF((in_dev)->cnf, \
						      MC_FORWARDING))
#define IN_DEV_RPFILTER(in_dev)		IN_DEV_ANDCONF((in_dev), RP_FILTER)
#define IN_DEV_SOURCE_ROUTE(in_dev)	IN_DEV_ANDCONF((in_dev), \
						       ACCEPT_SOURCE_ROUTE)
#define IN_DEV_BOOTP_RELAY(in_dev)	IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)

#define IN_DEV_LOG_MARTIANS(in_dev)	IN_DEV_ORCONF((in_dev), LOG_MARTIANS)
#define IN_DEV_PROXY_ARP(in_dev)	IN_DEV_ORCONF((in_dev), PROXY_ARP)
#define IN_DEV_SHARED_MEDIA(in_dev)	IN_DEV_ORCONF((in_dev), SHARED_MEDIA)
#define IN_DEV_TX_REDIRECTS(in_dev)	IN_DEV_ORCONF((in_dev), SEND_REDIRECTS)
#define IN_DEV_SEC_REDIRECTS(in_dev)	IN_DEV_ORCONF((in_dev), \
						      SECURE_REDIRECTS)
#define IN_DEV_IDTAG(in_dev)		IN_DEV_CONF_GET(in_dev, TAG)
#define IN_DEV_MEDIUM_ID(in_dev)	IN_DEV_CONF_GET(in_dev, MEDIUM_ID)
#define IN_DEV_PROMOTE_SECONDARIES(in_dev) \
					IN_DEV_ORCONF((in_dev), \
						      PROMOTE_SECONDARIES)
L
Linus Torvalds 已提交
94 95 96

#define IN_DEV_RX_REDIRECTS(in_dev) \
	((IN_DEV_FORWARD(in_dev) && \
97
	  IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
L
Linus Torvalds 已提交
98
	 || (!IN_DEV_FORWARD(in_dev) && \
99
	  IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
L
Linus Torvalds 已提交
100

101 102 103
#define IN_DEV_ARPFILTER(in_dev)	IN_DEV_ORCONF((in_dev), ARPFILTER)
#define IN_DEV_ARP_ANNOUNCE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
#define IN_DEV_ARP_IGNORE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
L
Linus Torvalds 已提交
104 105 106 107 108 109

struct in_ifaddr
{
	struct in_ifaddr	*ifa_next;
	struct in_device	*ifa_dev;
	struct rcu_head		rcu_head;
A
Al Viro 已提交
110 111 112 113 114
	__be32			ifa_local;
	__be32			ifa_address;
	__be32			ifa_mask;
	__be32			ifa_broadcast;
	__be32			ifa_anycast;
L
Linus Torvalds 已提交
115 116 117 118 119 120 121 122 123
	unsigned char		ifa_scope;
	unsigned char		ifa_flags;
	unsigned char		ifa_prefixlen;
	char			ifa_label[IFNAMSIZ];
};

extern int register_inetaddr_notifier(struct notifier_block *nb);
extern int unregister_inetaddr_notifier(struct notifier_block *nb);

A
Al Viro 已提交
124
extern struct net_device 	*ip_dev_find(__be32 addr);
A
Al Viro 已提交
125
extern int		inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
L
Linus Torvalds 已提交
126 127 128 129
extern int		devinet_ioctl(unsigned int cmd, void __user *);
extern void		devinet_init(void);
extern struct in_device *inetdev_init(struct net_device *dev);
extern struct in_device	*inetdev_by_index(int);
A
Al Viro 已提交
130
extern __be32		inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
A
Al Viro 已提交
131 132
extern __be32		inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
L
Linus Torvalds 已提交
133 134
extern void		inet_forward_change(void);

A
Al Viro 已提交
135
static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
L
Linus Torvalds 已提交
136 137 138 139 140 141 142 143
{
	return !((addr^ifa->ifa_address)&ifa->ifa_mask);
}

/*
 *	Check if a mask is acceptable.
 */
 
144
static __inline__ int bad_mask(__be32 mask, __be32 addr)
L
Linus Torvalds 已提交
145
{
146
	__u32 hmask;
L
Linus Torvalds 已提交
147 148
	if (addr & (mask = ~mask))
		return 1;
149 150
	hmask = ntohl(mask);
	if (hmask & (hmask+1))
L
Linus Torvalds 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163
		return 1;
	return 0;
}

#define for_primary_ifa(in_dev)	{ struct in_ifaddr *ifa; \
  for (ifa = (in_dev)->ifa_list; ifa && !(ifa->ifa_flags&IFA_F_SECONDARY); ifa = ifa->ifa_next)

#define for_ifa(in_dev)	{ struct in_ifaddr *ifa; \
  for (ifa = (in_dev)->ifa_list; ifa; ifa = ifa->ifa_next)


#define endfor_ifa(in_dev) }

164 165 166 167 168 169 170 171
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;
}

L
Linus Torvalds 已提交
172 173 174 175 176 177
static __inline__ struct in_device *
in_dev_get(const struct net_device *dev)
{
	struct in_device *in_dev;

	rcu_read_lock();
178
	in_dev = __in_dev_get_rcu(dev);
L
Linus Torvalds 已提交
179 180 181 182 183 184 185
	if (in_dev)
		atomic_inc(&in_dev->refcnt);
	rcu_read_unlock();
	return in_dev;
}

static __inline__ struct in_device *
186
__in_dev_get_rtnl(const struct net_device *dev)
L
Linus Torvalds 已提交
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
{
	return (struct in_device*)dev->ip_ptr;
}

extern void in_dev_finish_destroy(struct in_device *idev);

static inline void in_dev_put(struct in_device *idev)
{
	if (atomic_dec_and_test(&idev->refcnt))
		in_dev_finish_destroy(idev);
}

#define __in_dev_put(idev)  atomic_dec(&(idev)->refcnt)
#define in_dev_hold(idev)   atomic_inc(&(idev)->refcnt)

#endif /* __KERNEL__ */

A
Al Viro 已提交
204
static __inline__ __be32 inet_make_mask(int logmask)
L
Linus Torvalds 已提交
205 206 207 208 209 210
{
	if (logmask)
		return htonl(~((1<<(32-logmask))-1));
	return 0;
}

211
static __inline__ int inet_mask_len(__be32 mask)
L
Linus Torvalds 已提交
212
{
213 214
	__u32 hmask = ntohl(mask);
	if (!hmask)
L
Linus Torvalds 已提交
215
		return 0;
216
	return 32 - ffz(~hmask);
L
Linus Torvalds 已提交
217 218 219 220
}


#endif /* _LINUX_INETDEVICE_H */