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
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/rcupdate.h>
#include <linux/timer.h>
11
#include <linux/sysctl.h>
L
Linus Torvalds 已提交
12 13 14 15

struct ipv4_devconf
{
	void	*sysctl;
16
	int	data[__NET_IPV4_CONF_MAX - 1];
17
	DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1);
L
Linus Torvalds 已提交
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 45
};

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;
};

46
#define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
47 48
#define IPV4_DEVCONF_ALL(net, attr) \
	IPV4_DEVCONF((*(net)->ipv4.devconf_all), attr)
49 50 51 52 53 54 55 56 57 58 59

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--;
60
	set_bit(index, in_dev->cnf.state);
61 62 63
	in_dev->cnf.data[index] = val;
}

64 65 66 67 68
static inline void ipv4_devconf_setall(struct in_device *in_dev)
{
	bitmap_fill(in_dev->cnf.state, __NET_IPV4_CONF_MAX - 1);
}

69 70 71 72 73 74
#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) \
75 76
	(IPV4_DEVCONF_ALL(in_dev->dev->nd_net, attr) && \
	 IN_DEV_CONF_GET((in_dev), attr))
77
#define IN_DEV_ORCONF(in_dev, attr) \
78 79
	(IPV4_DEVCONF_ALL(in_dev->dev->nd_net, attr) || \
	 IN_DEV_CONF_GET((in_dev), attr))
80
#define IN_DEV_MAXCONF(in_dev, attr) \
81 82
	(max(IPV4_DEVCONF_ALL(in_dev->dev->nd_net, attr), \
	     IN_DEV_CONF_GET((in_dev), attr)))
83 84

#define IN_DEV_FORWARD(in_dev)		IN_DEV_CONF_GET((in_dev), FORWARDING)
85
#define IN_DEV_MFORWARD(in_dev)		IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
#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 已提交
102 103 104

#define IN_DEV_RX_REDIRECTS(in_dev) \
	((IN_DEV_FORWARD(in_dev) && \
105
	  IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
L
Linus Torvalds 已提交
106
	 || (!IN_DEV_FORWARD(in_dev) && \
107
	  IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
L
Linus Torvalds 已提交
108

109 110 111
#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 已提交
112 113 114 115 116 117

struct in_ifaddr
{
	struct in_ifaddr	*ifa_next;
	struct in_device	*ifa_dev;
	struct rcu_head		rcu_head;
A
Al Viro 已提交
118 119 120 121 122
	__be32			ifa_local;
	__be32			ifa_address;
	__be32			ifa_mask;
	__be32			ifa_broadcast;
	__be32			ifa_anycast;
L
Linus Torvalds 已提交
123 124 125 126 127 128 129 130 131
	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 已提交
132
extern struct net_device 	*ip_dev_find(__be32 addr);
A
Al Viro 已提交
133
extern int		inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
L
Linus Torvalds 已提交
134 135 136
extern int		devinet_ioctl(unsigned int cmd, void __user *);
extern void		devinet_init(void);
extern struct in_device	*inetdev_by_index(int);
A
Al Viro 已提交
137
extern __be32		inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
A
Al Viro 已提交
138 139
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 已提交
140

A
Al Viro 已提交
141
static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
L
Linus Torvalds 已提交
142 143 144 145 146 147 148 149
{
	return !((addr^ifa->ifa_address)&ifa->ifa_mask);
}

/*
 *	Check if a mask is acceptable.
 */
 
150
static __inline__ int bad_mask(__be32 mask, __be32 addr)
L
Linus Torvalds 已提交
151
{
152
	__u32 hmask;
L
Linus Torvalds 已提交
153 154
	if (addr & (mask = ~mask))
		return 1;
155 156
	hmask = ntohl(mask);
	if (hmask & (hmask+1))
L
Linus Torvalds 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169
		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) }

170 171 172 173 174 175 176 177
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 已提交
178 179 180 181 182 183
static __inline__ struct in_device *
in_dev_get(const struct net_device *dev)
{
	struct in_device *in_dev;

	rcu_read_lock();
184
	in_dev = __in_dev_get_rcu(dev);
L
Linus Torvalds 已提交
185 186 187 188 189 190 191
	if (in_dev)
		atomic_inc(&in_dev->refcnt);
	rcu_read_unlock();
	return in_dev;
}

static __inline__ struct in_device *
192
__in_dev_get_rtnl(const struct net_device *dev)
L
Linus Torvalds 已提交
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
{
	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 已提交
210
static __inline__ __be32 inet_make_mask(int logmask)
L
Linus Torvalds 已提交
211 212 213 214 215 216
{
	if (logmask)
		return htonl(~((1<<(32-logmask))-1));
	return 0;
}

217
static __inline__ int inet_mask_len(__be32 mask)
L
Linus Torvalds 已提交
218
{
219 220
	__u32 hmask = ntohl(mask);
	if (!hmask)
L
Linus Torvalds 已提交
221
		return 0;
222
	return 32 - ffz(~hmask);
L
Linus Torvalds 已提交
223 224 225 226
}


#endif /* _LINUX_INETDEVICE_H */