inetdevice.h 7.7 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
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,
41
	IPV4_DEVCONF_ROUTE_LOCALNET,
42 43 44
	__IPV4_DEVCONF_MAX
};

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

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

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

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

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

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

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

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

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

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

143
#define IN_DEV_ARPFILTER(in_dev)	IN_DEV_ORCONF((in_dev), ARPFILTER)
144
#define IN_DEV_ARP_ACCEPT(in_dev)	IN_DEV_ORCONF((in_dev), ARP_ACCEPT)
145 146
#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)
147
#define IN_DEV_ARP_NOTIFY(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
L
Linus Torvalds 已提交
148

E
Eric Dumazet 已提交
149
struct in_ifaddr {
150
	struct hlist_node	hash;
L
Linus Torvalds 已提交
151 152 153
	struct in_ifaddr	*ifa_next;
	struct in_device	*ifa_dev;
	struct rcu_head		rcu_head;
A
Al Viro 已提交
154 155 156 157
	__be32			ifa_local;
	__be32			ifa_address;
	__be32			ifa_mask;
	__be32			ifa_broadcast;
L
Linus Torvalds 已提交
158 159 160 161 162 163 164 165 166
	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 已提交
167 168 169 170 171 172
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 已提交
173
extern int		inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
174
extern int		devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
L
Linus Torvalds 已提交
175
extern void		devinet_init(void);
176
extern struct in_device	*inetdev_by_index(struct net *, int);
A
Al Viro 已提交
177
extern __be32		inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
178
extern __be32		inet_confirm_addr(struct in_device *in_dev, __be32 dst, __be32 local, int scope);
A
Al Viro 已提交
179
extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
L
Linus Torvalds 已提交
180

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

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

210 211
static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev)
{
E
Eric Dumazet 已提交
212
	return rcu_dereference(dev->ip_ptr);
213 214
}

E
Eric Dumazet 已提交
215
static inline struct in_device *in_dev_get(const struct net_device *dev)
L
Linus Torvalds 已提交
216 217 218 219
{
	struct in_device *in_dev;

	rcu_read_lock();
220
	in_dev = __in_dev_get_rcu(dev);
L
Linus Torvalds 已提交
221 222 223 224 225 226
	if (in_dev)
		atomic_inc(&in_dev->refcnt);
	rcu_read_unlock();
	return in_dev;
}

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

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

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


#endif /* _LINUX_INETDEVICE_H */