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

E
Eric Dumazet 已提交
44
struct ipv4_devconf {
L
Linus Torvalds 已提交
45
	void	*sysctl;
46 47
	int	data[__IPV4_DEVCONF_MAX - 1];
	DECLARE_BITMAP(state, __IPV4_DEVCONF_MAX - 1);
L
Linus Torvalds 已提交
48 49
};

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

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

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

91 92
static inline void ipv4_devconf_setall(struct in_device *in_dev)
{
93
	bitmap_fill(in_dev->cnf.state, __IPV4_DEVCONF_MAX - 1);
94 95
}

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

#define IN_DEV_ANDCONF(in_dev, attr) \
102
	(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr) && \
103
	 IN_DEV_CONF_GET((in_dev), attr))
104
#define IN_DEV_ORCONF(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_MAXCONF(in_dev, attr) \
108
	(max(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr), \
109
	     IN_DEV_CONF_GET((in_dev), attr)))
110 111

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

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

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

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

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

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

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

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

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

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

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

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


#endif /* _LINUX_INETDEVICE_H */