inetdevice.h 7.5 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>
E
Eric Dumazet 已提交
12
#include <linux/rtnetlink.h>
L
Linus Torvalds 已提交
13

14 15 16 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
enum
{
	IPV4_DEVCONF_FORWARDING=1,
	IPV4_DEVCONF_MC_FORWARDING,
	IPV4_DEVCONF_PROXY_ARP,
	IPV4_DEVCONF_ACCEPT_REDIRECTS,
	IPV4_DEVCONF_SECURE_REDIRECTS,
	IPV4_DEVCONF_SEND_REDIRECTS,
	IPV4_DEVCONF_SHARED_MEDIA,
	IPV4_DEVCONF_RP_FILTER,
	IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE,
	IPV4_DEVCONF_BOOTP_RELAY,
	IPV4_DEVCONF_LOG_MARTIANS,
	IPV4_DEVCONF_TAG,
	IPV4_DEVCONF_ARPFILTER,
	IPV4_DEVCONF_MEDIUM_ID,
	IPV4_DEVCONF_NOXFRM,
	IPV4_DEVCONF_NOPOLICY,
	IPV4_DEVCONF_FORCE_IGMP_VERSION,
	IPV4_DEVCONF_ARP_ANNOUNCE,
	IPV4_DEVCONF_ARP_IGNORE,
	IPV4_DEVCONF_PROMOTE_SECONDARIES,
	IPV4_DEVCONF_ARP_ACCEPT,
	IPV4_DEVCONF_ARP_NOTIFY,
	IPV4_DEVCONF_ACCEPT_LOCAL,
	IPV4_DEVCONF_SRC_VMARK,
	IPV4_DEVCONF_PROXY_ARP_PVLAN,
	__IPV4_DEVCONF_MAX
};

T
Thomas Graf 已提交
44 45
#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)

E
Eric Dumazet 已提交
46
struct ipv4_devconf {
L
Linus Torvalds 已提交
47
	void	*sysctl;
T
Thomas Graf 已提交
48 49
	int	data[IPV4_DEVCONF_MAX];
	DECLARE_BITMAP(state, IPV4_DEVCONF_MAX);
L
Linus Torvalds 已提交
50 51
};

E
Eric Dumazet 已提交
52
struct in_device {
L
Linus Torvalds 已提交
53 54 55 56
	struct net_device	*dev;
	atomic_t		refcnt;
	int			dead;
	struct in_ifaddr	*ifa_list;	/* IP ifaddr chain		*/
57 58
	struct ip_mc_list __rcu	*mc_list;	/* IP multicast filter chain    */
	int			mc_count;	/* Number of installed mcasts	*/
L
Linus Torvalds 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
	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;
};

75
#define IPV4_DEVCONF(cnf, attr) ((cnf).data[IPV4_DEVCONF_ ## attr - 1])
76 77
#define IPV4_DEVCONF_ALL(net, attr) \
	IPV4_DEVCONF((*(net)->ipv4.devconf_all), attr)
78 79 80 81 82 83 84 85 86 87 88

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--;
89
	set_bit(index, in_dev->cnf.state);
90 91 92
	in_dev->cnf.data[index] = val;
}

93 94
static inline void ipv4_devconf_setall(struct in_device *in_dev)
{
T
Thomas Graf 已提交
95
	bitmap_fill(in_dev->cnf.state, IPV4_DEVCONF_MAX);
96 97
}

98
#define IN_DEV_CONF_GET(in_dev, attr) \
99
	ipv4_devconf_get((in_dev), IPV4_DEVCONF_ ## attr)
100
#define IN_DEV_CONF_SET(in_dev, attr, val) \
101
	ipv4_devconf_set((in_dev), IPV4_DEVCONF_ ## attr, (val))
102 103

#define IN_DEV_ANDCONF(in_dev, attr) \
104
	(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr) && \
105
	 IN_DEV_CONF_GET((in_dev), attr))
106
#define IN_DEV_ORCONF(in_dev, attr) \
107
	(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr) || \
108
	 IN_DEV_CONF_GET((in_dev), attr))
109
#define IN_DEV_MAXCONF(in_dev, attr) \
110
	(max(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr), \
111
	     IN_DEV_CONF_GET((in_dev), attr)))
112 113

#define IN_DEV_FORWARD(in_dev)		IN_DEV_CONF_GET((in_dev), FORWARDING)
114
#define IN_DEV_MFORWARD(in_dev)		IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
115
#define IN_DEV_RPFILTER(in_dev)		IN_DEV_MAXCONF((in_dev), RP_FILTER)
116
#define IN_DEV_SRC_VMARK(in_dev)    	IN_DEV_ORCONF((in_dev), SRC_VMARK)
117 118
#define IN_DEV_SOURCE_ROUTE(in_dev)	IN_DEV_ANDCONF((in_dev), \
						       ACCEPT_SOURCE_ROUTE)
119
#define IN_DEV_ACCEPT_LOCAL(in_dev)	IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL)
120 121 122 123
#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)
124
#define IN_DEV_PROXY_ARP_PVLAN(in_dev)	IN_DEV_CONF_GET(in_dev, PROXY_ARP_PVLAN)
125 126 127 128 129 130 131 132 133
#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 已提交
134 135 136

#define IN_DEV_RX_REDIRECTS(in_dev) \
	((IN_DEV_FORWARD(in_dev) && \
137
	  IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
L
Linus Torvalds 已提交
138
	 || (!IN_DEV_FORWARD(in_dev) && \
139
	  IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
L
Linus Torvalds 已提交
140

141 142 143
#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)
144
#define IN_DEV_ARP_NOTIFY(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
L
Linus Torvalds 已提交
145

E
Eric Dumazet 已提交
146
struct in_ifaddr {
L
Linus Torvalds 已提交
147 148 149
	struct in_ifaddr	*ifa_next;
	struct in_device	*ifa_dev;
	struct rcu_head		rcu_head;
A
Al Viro 已提交
150 151 152 153
	__be32			ifa_local;
	__be32			ifa_address;
	__be32			ifa_mask;
	__be32			ifa_broadcast;
L
Linus Torvalds 已提交
154 155 156 157 158 159 160 161 162
	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);

E
Eric Dumazet 已提交
163 164 165 166 167 168
extern struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref);
static inline struct net_device *ip_dev_find(struct net *net, __be32 addr)
{
	return __ip_dev_find(net, addr, true);
}

A
Al Viro 已提交
169
extern int		inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
170
extern int		devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
L
Linus Torvalds 已提交
171
extern void		devinet_init(void);
172
extern struct in_device	*inetdev_by_index(struct net *, int);
A
Al Viro 已提交
173
extern __be32		inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
174
extern __be32		inet_confirm_addr(struct in_device *in_dev, __be32 dst, __be32 local, int scope);
A
Al Viro 已提交
175
extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
L
Linus Torvalds 已提交
176

A
Al Viro 已提交
177
static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
L
Linus Torvalds 已提交
178 179 180 181 182 183 184 185
{
	return !((addr^ifa->ifa_address)&ifa->ifa_mask);
}

/*
 *	Check if a mask is acceptable.
 */
 
186
static __inline__ int bad_mask(__be32 mask, __be32 addr)
L
Linus Torvalds 已提交
187
{
188
	__u32 hmask;
L
Linus Torvalds 已提交
189 190
	if (addr & (mask = ~mask))
		return 1;
191 192
	hmask = ntohl(mask);
	if (hmask & (hmask+1))
L
Linus Torvalds 已提交
193 194 195 196 197 198 199 200 201 202 203 204 205
		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) }

206 207
static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev)
{
E
Eric Dumazet 已提交
208
	return rcu_dereference(dev->ip_ptr);
209 210
}

E
Eric Dumazet 已提交
211
static inline struct in_device *in_dev_get(const struct net_device *dev)
L
Linus Torvalds 已提交
212 213 214 215
{
	struct in_device *in_dev;

	rcu_read_lock();
216
	in_dev = __in_dev_get_rcu(dev);
L
Linus Torvalds 已提交
217 218 219 220 221 222
	if (in_dev)
		atomic_inc(&in_dev->refcnt);
	rcu_read_unlock();
	return in_dev;
}

E
Eric Dumazet 已提交
223
static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
L
Linus Torvalds 已提交
224
{
225
	return rtnl_dereference(dev->ip_ptr);
L
Linus Torvalds 已提交
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
}

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 已提交
241
static __inline__ __be32 inet_make_mask(int logmask)
L
Linus Torvalds 已提交
242 243 244 245 246 247
{
	if (logmask)
		return htonl(~((1<<(32-logmask))-1));
	return 0;
}

248
static __inline__ int inet_mask_len(__be32 mask)
L
Linus Torvalds 已提交
249
{
250 251
	__u32 hmask = ntohl(mask);
	if (!hmask)
L
Linus Torvalds 已提交
252
		return 0;
253
	return 32 - ffz(~hmask);
L
Linus Torvalds 已提交
254 255 256 257
}


#endif /* _LINUX_INETDEVICE_H */