diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /include/net/route.h | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'include/net/route.h')
-rw-r--r-- | include/net/route.h | 224 |
1 files changed, 158 insertions, 66 deletions
diff --git a/include/net/route.h b/include/net/route.h index 7e5e73bfa4de..db7b3432f07c 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -35,44 +35,52 @@ | |||
35 | #include <linux/cache.h> | 35 | #include <linux/cache.h> |
36 | #include <linux/security.h> | 36 | #include <linux/security.h> |
37 | 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 | 38 | #define RTO_ONLINK 0x01 |
43 | 39 | ||
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)) | 40 | #define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE)) |
49 | 41 | ||
50 | struct fib_nh; | 42 | struct fib_nh; |
51 | struct inet_peer; | 43 | struct inet_peer; |
44 | struct fib_info; | ||
52 | struct rtable { | 45 | struct rtable { |
53 | struct dst_entry dst; | 46 | struct dst_entry dst; |
54 | 47 | ||
55 | /* Cache lookup keys */ | 48 | /* Lookup key. */ |
56 | struct flowi fl; | 49 | __be32 rt_key_dst; |
50 | __be32 rt_key_src; | ||
57 | 51 | ||
58 | struct in_device *idev; | ||
59 | |||
60 | int rt_genid; | 52 | int rt_genid; |
61 | unsigned rt_flags; | 53 | unsigned rt_flags; |
62 | __u16 rt_type; | 54 | __u16 rt_type; |
55 | __u8 rt_key_tos; | ||
63 | 56 | ||
64 | __be32 rt_dst; /* Path destination */ | 57 | __be32 rt_dst; /* Path destination */ |
65 | __be32 rt_src; /* Path source */ | 58 | __be32 rt_src; /* Path source */ |
59 | int rt_route_iif; | ||
66 | int rt_iif; | 60 | int rt_iif; |
61 | int rt_oif; | ||
62 | __u32 rt_mark; | ||
67 | 63 | ||
68 | /* Info on neighbour */ | 64 | /* Info on neighbour */ |
69 | __be32 rt_gateway; | 65 | __be32 rt_gateway; |
70 | 66 | ||
71 | /* Miscellaneous cached information */ | 67 | /* Miscellaneous cached information */ |
72 | __be32 rt_spec_dst; /* RFC1122 specific destination */ | 68 | __be32 rt_spec_dst; /* RFC1122 specific destination */ |
69 | u32 rt_peer_genid; | ||
73 | struct inet_peer *peer; /* long-living peer info */ | 70 | struct inet_peer *peer; /* long-living peer info */ |
71 | struct fib_info *fi; /* for client ref to shared metrics */ | ||
74 | }; | 72 | }; |
75 | 73 | ||
74 | static inline bool rt_is_input_route(struct rtable *rt) | ||
75 | { | ||
76 | return rt->rt_route_iif != 0; | ||
77 | } | ||
78 | |||
79 | static inline bool rt_is_output_route(struct rtable *rt) | ||
80 | { | ||
81 | return rt->rt_route_iif == 0; | ||
82 | } | ||
83 | |||
76 | struct ip_rt_acct { | 84 | struct ip_rt_acct { |
77 | __u32 o_bytes; | 85 | __u32 o_bytes; |
78 | __u32 o_packets; | 86 | __u32 o_packets; |
@@ -106,10 +114,57 @@ extern int ip_rt_init(void); | |||
106 | extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, | 114 | extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, |
107 | __be32 src, struct net_device *dev); | 115 | __be32 src, struct net_device *dev); |
108 | extern void rt_cache_flush(struct net *net, int how); | 116 | extern void rt_cache_flush(struct net *net, int how); |
109 | extern void rt_cache_flush_batch(void); | 117 | extern void rt_cache_flush_batch(struct net *net); |
110 | extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); | 118 | extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp); |
111 | extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); | 119 | extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp, |
112 | extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); | 120 | struct sock *sk); |
121 | extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); | ||
122 | |||
123 | static inline struct rtable *ip_route_output_key(struct net *net, struct flowi4 *flp) | ||
124 | { | ||
125 | return ip_route_output_flow(net, flp, NULL); | ||
126 | } | ||
127 | |||
128 | static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, | ||
129 | __be32 saddr, u8 tos, int oif) | ||
130 | { | ||
131 | struct flowi4 fl4 = { | ||
132 | .flowi4_oif = oif, | ||
133 | .daddr = daddr, | ||
134 | .saddr = saddr, | ||
135 | .flowi4_tos = tos, | ||
136 | }; | ||
137 | return ip_route_output_key(net, &fl4); | ||
138 | } | ||
139 | |||
140 | static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi4 *fl4, | ||
141 | struct sock *sk, | ||
142 | __be32 daddr, __be32 saddr, | ||
143 | __be16 dport, __be16 sport, | ||
144 | __u8 proto, __u8 tos, int oif) | ||
145 | { | ||
146 | flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos, | ||
147 | RT_SCOPE_UNIVERSE, proto, | ||
148 | sk ? inet_sk_flowi_flags(sk) : 0, | ||
149 | daddr, saddr, dport, sport); | ||
150 | if (sk) | ||
151 | security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); | ||
152 | return ip_route_output_flow(net, fl4, sk); | ||
153 | } | ||
154 | |||
155 | static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4, | ||
156 | __be32 daddr, __be32 saddr, | ||
157 | __be32 gre_key, __u8 tos, int oif) | ||
158 | { | ||
159 | memset(fl4, 0, sizeof(*fl4)); | ||
160 | fl4->flowi4_oif = oif; | ||
161 | fl4->daddr = daddr; | ||
162 | fl4->saddr = saddr; | ||
163 | fl4->flowi4_tos = tos; | ||
164 | fl4->flowi4_proto = IPPROTO_GRE; | ||
165 | fl4->fl4_gre_key = gre_key; | ||
166 | return ip_route_output_key(net, fl4); | ||
167 | } | ||
113 | 168 | ||
114 | extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, | 169 | extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, |
115 | u8 tos, struct net_device *devin, bool noref); | 170 | u8 tos, struct net_device *devin, bool noref); |
@@ -126,18 +181,20 @@ static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 s | |||
126 | return ip_route_input_common(skb, dst, src, tos, devin, true); | 181 | return ip_route_input_common(skb, dst, src, tos, devin, true); |
127 | } | 182 | } |
128 | 183 | ||
129 | extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev); | 184 | extern unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, |
185 | unsigned short new_mtu, struct net_device *dev); | ||
130 | extern void ip_rt_send_redirect(struct sk_buff *skb); | 186 | extern void ip_rt_send_redirect(struct sk_buff *skb); |
131 | 187 | ||
132 | extern unsigned inet_addr_type(struct net *net, __be32 addr); | 188 | extern unsigned inet_addr_type(struct net *net, __be32 addr); |
133 | extern unsigned inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr); | 189 | extern unsigned inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr); |
134 | extern void ip_rt_multicast_event(struct in_device *); | 190 | extern void ip_rt_multicast_event(struct in_device *); |
135 | extern int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg); | 191 | extern int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg); |
136 | extern void ip_rt_get_source(u8 *src, struct rtable *rt); | 192 | extern void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt); |
137 | extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); | 193 | extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); |
138 | 194 | ||
139 | struct in_ifaddr; | 195 | struct in_ifaddr; |
140 | extern void fib_add_ifaddr(struct in_ifaddr *); | 196 | extern void fib_add_ifaddr(struct in_ifaddr *); |
197 | extern void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); | ||
141 | 198 | ||
142 | static inline void ip_rt_put(struct rtable * rt) | 199 | static inline void ip_rt_put(struct rtable * rt) |
143 | { | 200 | { |
@@ -154,69 +211,93 @@ static inline char rt_tos2priority(u8 tos) | |||
154 | return ip_tos2prio[IPTOS_TOS(tos)>>1]; | 211 | return ip_tos2prio[IPTOS_TOS(tos)>>1]; |
155 | } | 212 | } |
156 | 213 | ||
157 | static inline int ip_route_connect(struct rtable **rp, __be32 dst, | 214 | /* ip_route_connect() and ip_route_newports() work in tandem whilst |
158 | __be32 src, u32 tos, int oif, u8 protocol, | 215 | * binding a socket for a new outgoing connection. |
159 | __be16 sport, __be16 dport, struct sock *sk, | 216 | * |
160 | int flags) | 217 | * In order to use IPSEC properly, we must, in the end, have a |
218 | * route that was looked up using all available keys including source | ||
219 | * and destination ports. | ||
220 | * | ||
221 | * However, if a source port needs to be allocated (the user specified | ||
222 | * a wildcard source port) we need to obtain addressing information | ||
223 | * in order to perform that allocation. | ||
224 | * | ||
225 | * So ip_route_connect() looks up a route using wildcarded source and | ||
226 | * destination ports in the key, simply so that we can get a pair of | ||
227 | * addresses to use for port allocation. | ||
228 | * | ||
229 | * Later, once the ports are allocated, ip_route_newports() will make | ||
230 | * another route lookup if needed to make sure we catch any IPSEC | ||
231 | * rules keyed on the port information. | ||
232 | * | ||
233 | * The callers allocate the flow key on their stack, and must pass in | ||
234 | * the same flowi4 object to both the ip_route_connect() and the | ||
235 | * ip_route_newports() calls. | ||
236 | */ | ||
237 | |||
238 | static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 src, | ||
239 | u32 tos, int oif, u8 protocol, | ||
240 | __be16 sport, __be16 dport, | ||
241 | struct sock *sk, bool can_sleep) | ||
161 | { | 242 | { |
162 | struct flowi fl = { .oif = oif, | 243 | __u8 flow_flags = 0; |
163 | .mark = sk->sk_mark, | 244 | |
164 | .nl_u = { .ip4_u = { .daddr = dst, | 245 | if (inet_sk(sk)->transparent) |
165 | .saddr = src, | 246 | flow_flags |= FLOWI_FLAG_ANYSRC; |
166 | .tos = tos } }, | 247 | if (protocol == IPPROTO_TCP) |
167 | .proto = protocol, | 248 | flow_flags |= FLOWI_FLAG_PRECOW_METRICS; |
168 | .uli_u = { .ports = | 249 | if (can_sleep) |
169 | { .sport = sport, | 250 | flow_flags |= FLOWI_FLAG_CAN_SLEEP; |
170 | .dport = dport } } }; | 251 | |
252 | flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, | ||
253 | protocol, flow_flags, dst, src, dport, sport); | ||
254 | } | ||
171 | 255 | ||
172 | int err; | 256 | static inline struct rtable *ip_route_connect(struct flowi4 *fl4, |
257 | __be32 dst, __be32 src, u32 tos, | ||
258 | int oif, u8 protocol, | ||
259 | __be16 sport, __be16 dport, | ||
260 | struct sock *sk, bool can_sleep) | ||
261 | { | ||
173 | struct net *net = sock_net(sk); | 262 | struct net *net = sock_net(sk); |
263 | struct rtable *rt; | ||
174 | 264 | ||
175 | if (inet_sk(sk)->transparent) | 265 | ip_route_connect_init(fl4, dst, src, tos, oif, protocol, |
176 | fl.flags |= FLOWI_FLAG_ANYSRC; | 266 | sport, dport, sk, can_sleep); |
177 | 267 | ||
178 | if (!dst || !src) { | 268 | if (!dst || !src) { |
179 | err = __ip_route_output_key(net, rp, &fl); | 269 | rt = __ip_route_output_key(net, fl4); |
180 | if (err) | 270 | if (IS_ERR(rt)) |
181 | return err; | 271 | return rt; |
182 | fl.fl4_dst = (*rp)->rt_dst; | 272 | ip_rt_put(rt); |
183 | fl.fl4_src = (*rp)->rt_src; | ||
184 | ip_rt_put(*rp); | ||
185 | *rp = NULL; | ||
186 | } | 273 | } |
187 | security_sk_classify_flow(sk, &fl); | 274 | security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); |
188 | return ip_route_output_flow(net, rp, &fl, sk, flags); | 275 | return ip_route_output_flow(net, fl4, sk); |
189 | } | 276 | } |
190 | 277 | ||
191 | static inline int ip_route_newports(struct rtable **rp, u8 protocol, | 278 | static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable *rt, |
192 | __be16 sport, __be16 dport, struct sock *sk) | 279 | __be16 orig_sport, __be16 orig_dport, |
193 | { | 280 | __be16 sport, __be16 dport, |
194 | if (sport != (*rp)->fl.fl_ip_sport || | 281 | struct sock *sk) |
195 | dport != (*rp)->fl.fl_ip_dport) { | 282 | { |
196 | struct flowi fl; | 283 | if (sport != orig_sport || dport != orig_dport) { |
197 | 284 | fl4->fl4_dport = dport; | |
198 | memcpy(&fl, &(*rp)->fl, sizeof(fl)); | 285 | fl4->fl4_sport = sport; |
199 | fl.fl_ip_sport = sport; | 286 | ip_rt_put(rt); |
200 | fl.fl_ip_dport = dport; | 287 | security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); |
201 | fl.proto = protocol; | 288 | return ip_route_output_flow(sock_net(sk), fl4, sk); |
202 | if (inet_sk(sk)->transparent) | ||
203 | fl.flags |= FLOWI_FLAG_ANYSRC; | ||
204 | ip_rt_put(*rp); | ||
205 | *rp = NULL; | ||
206 | security_sk_classify_flow(sk, &fl); | ||
207 | return ip_route_output_flow(sock_net(sk), rp, &fl, sk, 0); | ||
208 | } | 289 | } |
209 | return 0; | 290 | return rt; |
210 | } | 291 | } |
211 | 292 | ||
212 | extern void rt_bind_peer(struct rtable *rt, int create); | 293 | extern void rt_bind_peer(struct rtable *rt, __be32 daddr, int create); |
213 | 294 | ||
214 | static inline struct inet_peer *rt_get_peer(struct rtable *rt) | 295 | static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) |
215 | { | 296 | { |
216 | if (rt->peer) | 297 | if (rt->peer) |
217 | return rt->peer; | 298 | return rt->peer; |
218 | 299 | ||
219 | rt_bind_peer(rt, 0); | 300 | rt_bind_peer(rt, daddr, 0); |
220 | return rt->peer; | 301 | return rt->peer; |
221 | } | 302 | } |
222 | 303 | ||
@@ -225,4 +306,15 @@ static inline int inet_iif(const struct sk_buff *skb) | |||
225 | return skb_rtable(skb)->rt_iif; | 306 | return skb_rtable(skb)->rt_iif; |
226 | } | 307 | } |
227 | 308 | ||
309 | extern int sysctl_ip_default_ttl; | ||
310 | |||
311 | static inline int ip4_dst_hoplimit(const struct dst_entry *dst) | ||
312 | { | ||
313 | int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); | ||
314 | |||
315 | if (hoplimit == 0) | ||
316 | hoplimit = sysctl_ip_default_ttl; | ||
317 | return hoplimit; | ||
318 | } | ||
319 | |||
228 | #endif /* _ROUTE_H */ | 320 | #endif /* _ROUTE_H */ |