inetdevice.h 8.18 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5
#ifndef _LINUX_INETDEVICE_H
#define _LINUX_INETDEVICE_H

#ifdef __KERNEL__

6
#include <linux/bitmap.h>
Linus Torvalds's avatar
Linus Torvalds committed
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>
Eric Dumazet's avatar
Eric Dumazet committed
12
#include <linux/rtnetlink.h>
Linus Torvalds's avatar
Linus Torvalds committed
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
};

45 46
#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)

47
struct ipv4_devconf {
Linus Torvalds's avatar
Linus Torvalds committed
48
	void	*sysctl;
49 50
	int	data[IPV4_DEVCONF_MAX];
	DECLARE_BITMAP(state, IPV4_DEVCONF_MAX);
Linus Torvalds's avatar
Linus Torvalds committed
51 52
};

53
struct in_device {
Linus Torvalds's avatar
Linus Torvalds committed
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	*/
Linus Torvalds's avatar
Linus Torvalds committed
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)
{
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 108 109

#define IN_DEV_NET_ORCONF(in_dev, net, attr) \
	(IPV4_DEVCONF_ALL(net, attr) || \
110
	 IN_DEV_CONF_GET((in_dev), attr))
111 112 113 114

#define IN_DEV_ORCONF(in_dev, attr) \
	IN_DEV_NET_ORCONF(in_dev, dev_net(in_dev->dev), attr)

115
#define IN_DEV_MAXCONF(in_dev, attr) \
116
	(max(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr), \
117
	     IN_DEV_CONF_GET((in_dev), attr)))
118 119

#define IN_DEV_FORWARD(in_dev)		IN_DEV_CONF_GET((in_dev), FORWARDING)
120
#define IN_DEV_MFORWARD(in_dev)		IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
121
#define IN_DEV_RPFILTER(in_dev)		IN_DEV_MAXCONF((in_dev), RP_FILTER)
122
#define IN_DEV_SRC_VMARK(in_dev)    	IN_DEV_ORCONF((in_dev), SRC_VMARK)
123 124
#define IN_DEV_SOURCE_ROUTE(in_dev)	IN_DEV_ANDCONF((in_dev), \
						       ACCEPT_SOURCE_ROUTE)
125
#define IN_DEV_ACCEPT_LOCAL(in_dev)	IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL)
126 127 128 129
#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)
130
#define IN_DEV_PROXY_ARP_PVLAN(in_dev)	IN_DEV_CONF_GET(in_dev, PROXY_ARP_PVLAN)
131 132 133 134 135 136 137 138 139
#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)
140
#define IN_DEV_ROUTE_LOCALNET(in_dev)	IN_DEV_ORCONF(in_dev, ROUTE_LOCALNET)
141 142
#define IN_DEV_NET_ROUTE_LOCALNET(in_dev, net)	\
	IN_DEV_NET_ORCONF(in_dev, net, ROUTE_LOCALNET)
Linus Torvalds's avatar
Linus Torvalds committed
143 144 145

#define IN_DEV_RX_REDIRECTS(in_dev) \
	((IN_DEV_FORWARD(in_dev) && \
146
	  IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
Linus Torvalds's avatar
Linus Torvalds committed
147
	 || (!IN_DEV_FORWARD(in_dev) && \
148
	  IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
Linus Torvalds's avatar
Linus Torvalds committed
149

150
#define IN_DEV_ARPFILTER(in_dev)	IN_DEV_ORCONF((in_dev), ARPFILTER)
151
#define IN_DEV_ARP_ACCEPT(in_dev)	IN_DEV_ORCONF((in_dev), ARP_ACCEPT)
152 153
#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)
154
#define IN_DEV_ARP_NOTIFY(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
Linus Torvalds's avatar
Linus Torvalds committed
155

156
struct in_ifaddr {
157
	struct hlist_node	hash;
Linus Torvalds's avatar
Linus Torvalds committed
158 159 160
	struct in_ifaddr	*ifa_next;
	struct in_device	*ifa_dev;
	struct rcu_head		rcu_head;
161 162 163 164
	__be32			ifa_local;
	__be32			ifa_address;
	__be32			ifa_mask;
	__be32			ifa_broadcast;
Linus Torvalds's avatar
Linus Torvalds committed
165 166 167 168
	unsigned char		ifa_scope;
	unsigned char		ifa_flags;
	unsigned char		ifa_prefixlen;
	char			ifa_label[IFNAMSIZ];
169 170 171 172 173 174

	/* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */
	__u32			ifa_valid_lft;
	__u32			ifa_preferred_lft;
	unsigned long		ifa_cstamp; /* created timestamp */
	unsigned long		ifa_tstamp; /* updated timestamp */
Linus Torvalds's avatar
Linus Torvalds committed
175 176 177 178 179
};

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

180 181 182
extern void inet_netconf_notify_devconf(struct net *net, int type, int ifindex,
					struct ipv4_devconf *devconf);

183 184 185 186 187 188
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);
}

189
extern int		inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
190
extern int		devinet_ioctl(struct net *net, unsigned int cmd, void __user *);
Linus Torvalds's avatar
Linus Torvalds committed
191
extern void		devinet_init(void);
192
extern struct in_device	*inetdev_by_index(struct net *, int);
193
extern __be32		inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
194
extern __be32		inet_confirm_addr(struct in_device *in_dev, __be32 dst, __be32 local, int scope);
195
extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
Linus Torvalds's avatar
Linus Torvalds committed
196

197
static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
Linus Torvalds's avatar
Linus Torvalds committed
198 199 200 201 202 203 204 205
{
	return !((addr^ifa->ifa_address)&ifa->ifa_mask);
}

/*
 *	Check if a mask is acceptable.
 */
 
206
static __inline__ int bad_mask(__be32 mask, __be32 addr)
Linus Torvalds's avatar
Linus Torvalds committed
207
{
208
	__u32 hmask;
Linus Torvalds's avatar
Linus Torvalds committed
209 210
	if (addr & (mask = ~mask))
		return 1;
211 212
	hmask = ntohl(mask);
	if (hmask & (hmask+1))
Linus Torvalds's avatar
Linus Torvalds committed
213 214 215 216 217 218 219 220 221 222 223 224 225
		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) }

226 227
static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev)
{
Eric Dumazet's avatar
Eric Dumazet committed
228
	return rcu_dereference(dev->ip_ptr);
229 230
}

Eric Dumazet's avatar
Eric Dumazet committed
231
static inline struct in_device *in_dev_get(const struct net_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
232 233 234 235
{
	struct in_device *in_dev;

	rcu_read_lock();
236
	in_dev = __in_dev_get_rcu(dev);
Linus Torvalds's avatar
Linus Torvalds committed
237 238 239 240 241 242
	if (in_dev)
		atomic_inc(&in_dev->refcnt);
	rcu_read_unlock();
	return in_dev;
}

Eric Dumazet's avatar
Eric Dumazet committed
243
static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
244
{
245
	return rtnl_dereference(dev->ip_ptr);
Linus Torvalds's avatar
Linus Torvalds committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
}

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__ */

261
static __inline__ __be32 inet_make_mask(int logmask)
Linus Torvalds's avatar
Linus Torvalds committed
262 263 264 265 266 267
{
	if (logmask)
		return htonl(~((1<<(32-logmask))-1));
	return 0;
}

268
static __inline__ int inet_mask_len(__be32 mask)
Linus Torvalds's avatar
Linus Torvalds committed
269
{
270 271
	__u32 hmask = ntohl(mask);
	if (!hmask)
Linus Torvalds's avatar
Linus Torvalds committed
272
		return 0;
273
	return 32 - ffz(~hmask);
Linus Torvalds's avatar
Linus Torvalds committed
274 275 276 277
}


#endif /* _LINUX_INETDEVICE_H */