route.h revision 5e2b61f78411be25f0b84f97d5b5d312f184dfd1
1/*
2 * INET		An implementation of the TCP/IP protocol suite for the LINUX
3 *		operating system.  INET  is implemented using the  BSD Socket
4 *		interface as the means of communication with the user level.
5 *
6 *		Definitions for the IP router.
7 *
8 * Version:	@(#)route.h	1.0.4	05/27/93
9 *
10 * Authors:	Ross Biro
11 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Fixes:
13 *		Alan Cox	:	Reformatted. Added ip_rt_local()
14 *		Alan Cox	:	Support for TCP parameters.
15 *		Alexey Kuznetsov:	Major changes for new routing code.
16 *		Mike McLagan    :	Routing by source
17 *		Robert Olsson   :	Added rt_cache statistics
18 *
19 *		This program is free software; you can redistribute it and/or
20 *		modify it under the terms of the GNU General Public License
21 *		as published by the Free Software Foundation; either version
22 *		2 of the License, or (at your option) any later version.
23 */
24#ifndef _ROUTE_H
25#define _ROUTE_H
26
27#include <net/dst.h>
28#include <net/inetpeer.h>
29#include <net/flow.h>
30#include <net/inet_sock.h>
31#include <linux/in_route.h>
32#include <linux/rtnetlink.h>
33#include <linux/route.h>
34#include <linux/ip.h>
35#include <linux/cache.h>
36#include <linux/security.h>
37
38#ifndef __KERNEL__
39#warning This file is not supposed to be used outside of kernel.
40#endif
41
42#define RTO_ONLINK	0x01
43
44#define RTO_CONN	0
45/* RTO_CONN is not used (being alias for 0), but preserved not to break
46 * some modules referring to it. */
47
48#define RT_CONN_FLAGS(sk)   (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE))
49
50struct fib_nh;
51struct inet_peer;
52struct fib_info;
53struct rtable {
54	struct dst_entry	dst;
55
56	/* Lookup key. */
57	__be32			rt_key_dst;
58	__be32			rt_key_src;
59
60	int			rt_genid;
61	unsigned		rt_flags;
62	__u16			rt_type;
63	__u8			rt_tos;
64
65	__be32			rt_dst;	/* Path destination	*/
66	__be32			rt_src;	/* Path source		*/
67	int			rt_iif;
68	int			rt_oif;
69	__u32			rt_mark;
70
71	/* Info on neighbour */
72	__be32			rt_gateway;
73
74	/* Miscellaneous cached information */
75	__be32			rt_spec_dst; /* RFC1122 specific destination */
76	u32			rt_peer_genid;
77	struct inet_peer	*peer; /* long-living peer info */
78	struct fib_info		*fi; /* for client ref to shared metrics */
79};
80
81static inline bool rt_is_input_route(struct rtable *rt)
82{
83	return rt->rt_iif != 0;
84}
85
86static inline bool rt_is_output_route(struct rtable *rt)
87{
88	return rt->rt_iif == 0;
89}
90
91struct ip_rt_acct {
92	__u32 	o_bytes;
93	__u32 	o_packets;
94	__u32 	i_bytes;
95	__u32 	i_packets;
96};
97
98struct rt_cache_stat {
99        unsigned int in_hit;
100        unsigned int in_slow_tot;
101        unsigned int in_slow_mc;
102        unsigned int in_no_route;
103        unsigned int in_brd;
104        unsigned int in_martian_dst;
105        unsigned int in_martian_src;
106        unsigned int out_hit;
107        unsigned int out_slow_tot;
108        unsigned int out_slow_mc;
109        unsigned int gc_total;
110        unsigned int gc_ignored;
111        unsigned int gc_goal_miss;
112        unsigned int gc_dst_overflow;
113        unsigned int in_hlist_search;
114        unsigned int out_hlist_search;
115};
116
117extern struct ip_rt_acct __percpu *ip_rt_acct;
118
119struct in_device;
120extern int		ip_rt_init(void);
121extern void		ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
122				       __be32 src, struct net_device *dev);
123extern void		rt_cache_flush(struct net *net, int how);
124extern void		rt_cache_flush_batch(struct net *net);
125extern struct rtable *__ip_route_output_key(struct net *, const struct flowi *flp);
126extern struct rtable *ip_route_output_flow(struct net *, struct flowi *flp,
127					   struct sock *sk);
128extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig);
129
130static inline struct rtable *ip_route_output_key(struct net *net, struct flowi *flp)
131{
132	return ip_route_output_flow(net, flp, NULL);
133}
134
135extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
136				 u8 tos, struct net_device *devin, bool noref);
137
138static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
139				 u8 tos, struct net_device *devin)
140{
141	return ip_route_input_common(skb, dst, src, tos, devin, false);
142}
143
144static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
145				       u8 tos, struct net_device *devin)
146{
147	return ip_route_input_common(skb, dst, src, tos, devin, true);
148}
149
150extern unsigned short	ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev);
151extern void		ip_rt_send_redirect(struct sk_buff *skb);
152
153extern unsigned		inet_addr_type(struct net *net, __be32 addr);
154extern unsigned		inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr);
155extern void		ip_rt_multicast_event(struct in_device *);
156extern int		ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
157extern void		ip_rt_get_source(u8 *src, struct rtable *rt);
158extern int		ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb);
159
160struct in_ifaddr;
161extern void fib_add_ifaddr(struct in_ifaddr *);
162
163static inline void ip_rt_put(struct rtable * rt)
164{
165	if (rt)
166		dst_release(&rt->dst);
167}
168
169#define IPTOS_RT_MASK	(IPTOS_TOS_MASK & ~3)
170
171extern const __u8 ip_tos2prio[16];
172
173static inline char rt_tos2priority(u8 tos)
174{
175	return ip_tos2prio[IPTOS_TOS(tos)>>1];
176}
177
178static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos,
179					      int oif, u8 protocol,
180					      __be16 sport, __be16 dport,
181					      struct sock *sk, bool can_sleep)
182{
183	struct flowi fl = { .oif = oif,
184			    .mark = sk->sk_mark,
185			    .fl4_dst = dst,
186			    .fl4_src = src,
187			    .fl4_tos = tos,
188			    .proto = protocol,
189			    .fl_ip_sport = sport,
190			    .fl_ip_dport = dport };
191	struct net *net = sock_net(sk);
192	struct rtable *rt;
193
194	if (inet_sk(sk)->transparent)
195		fl.flags |= FLOWI_FLAG_ANYSRC;
196	if (protocol == IPPROTO_TCP)
197		fl.flags |= FLOWI_FLAG_PRECOW_METRICS;
198	if (can_sleep)
199		fl.flags |= FLOWI_FLAG_CAN_SLEEP;
200
201	if (!dst || !src) {
202		rt = __ip_route_output_key(net, &fl);
203		if (IS_ERR(rt))
204			return rt;
205		fl.fl4_dst = rt->rt_dst;
206		fl.fl4_src = rt->rt_src;
207		ip_rt_put(rt);
208	}
209	security_sk_classify_flow(sk, &fl);
210	return ip_route_output_flow(net, &fl, sk);
211}
212
213static inline struct rtable *ip_route_newports(struct rtable *rt,
214					       u8 protocol, __be16 orig_sport,
215					       __be16 orig_dport, __be16 sport,
216					       __be16 dport, struct sock *sk)
217{
218	if (sport != orig_sport || dport != orig_dport) {
219		struct flowi fl = { .oif = rt->rt_oif,
220				    .mark = rt->rt_mark,
221				    .fl4_dst = rt->rt_key_dst,
222				    .fl4_src = rt->rt_key_src,
223				    .fl4_tos = rt->rt_tos,
224				    .proto = protocol,
225				    .fl_ip_sport = sport,
226				    .fl_ip_dport = dport };
227
228		if (inet_sk(sk)->transparent)
229			fl.flags |= FLOWI_FLAG_ANYSRC;
230		if (protocol == IPPROTO_TCP)
231			fl.flags |= FLOWI_FLAG_PRECOW_METRICS;
232		ip_rt_put(rt);
233		security_sk_classify_flow(sk, &fl);
234		return ip_route_output_flow(sock_net(sk), &fl, sk);
235	}
236	return rt;
237}
238
239extern void rt_bind_peer(struct rtable *rt, int create);
240
241static inline struct inet_peer *rt_get_peer(struct rtable *rt)
242{
243	if (rt->peer)
244		return rt->peer;
245
246	rt_bind_peer(rt, 0);
247	return rt->peer;
248}
249
250static inline int inet_iif(const struct sk_buff *skb)
251{
252	return skb_rtable(skb)->rt_iif;
253}
254
255extern int sysctl_ip_default_ttl;
256
257static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
258{
259	int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
260
261	if (hoplimit == 0)
262		hoplimit = sysctl_ip_default_ttl;
263	return hoplimit;
264}
265
266#endif	/* _ROUTE_H */
267