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

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

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

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

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

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

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

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

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


#endif /* _LINUX_INETDEVICE_H */