aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r--net/ipv4/ip_output.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index eba64e2bd397..3324fbfe528a 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -69,6 +69,7 @@
69#include <net/ip.h> 69#include <net/ip.h>
70#include <net/protocol.h> 70#include <net/protocol.h>
71#include <net/route.h> 71#include <net/route.h>
72#include <net/xfrm.h>
72#include <linux/skbuff.h> 73#include <linux/skbuff.h>
73#include <net/sock.h> 74#include <net/sock.h>
74#include <net/arp.h> 75#include <net/arp.h>
@@ -85,6 +86,8 @@
85 86
86int sysctl_ip_default_ttl = IPDEFTTL; 87int sysctl_ip_default_ttl = IPDEFTTL;
87 88
89static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
90
88/* Generate a checksum for an outgoing IP datagram. */ 91/* Generate a checksum for an outgoing IP datagram. */
89__inline__ void ip_send_check(struct iphdr *iph) 92__inline__ void ip_send_check(struct iphdr *iph)
90{ 93{
@@ -202,13 +205,16 @@ static inline int ip_finish_output2(struct sk_buff *skb)
202 205
203static inline int ip_finish_output(struct sk_buff *skb) 206static inline int ip_finish_output(struct sk_buff *skb)
204{ 207{
205 struct net_device *dev = skb->dst->dev; 208#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
206 209 /* Policy lookup after SNAT yielded a new policy */
207 skb->dev = dev; 210 if (skb->dst->xfrm != NULL)
208 skb->protocol = htons(ETH_P_IP); 211 return xfrm4_output_finish(skb);
209 212#endif
210 return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, 213 if (skb->len > dst_mtu(skb->dst) &&
211 ip_finish_output2); 214 !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
215 return ip_fragment(skb, ip_finish_output2);
216 else
217 return ip_finish_output2(skb);
212} 218}
213 219
214int ip_mc_output(struct sk_buff *skb) 220int ip_mc_output(struct sk_buff *skb)
@@ -265,21 +271,21 @@ int ip_mc_output(struct sk_buff *skb)
265 newskb->dev, ip_dev_loopback_xmit); 271 newskb->dev, ip_dev_loopback_xmit);
266 } 272 }
267 273
268 if (skb->len > dst_mtu(&rt->u.dst)) 274 return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
269 return ip_fragment(skb, ip_finish_output); 275 ip_finish_output);
270 else
271 return ip_finish_output(skb);
272} 276}
273 277
274int ip_output(struct sk_buff *skb) 278int ip_output(struct sk_buff *skb)
275{ 279{
280 struct net_device *dev = skb->dst->dev;
281
276 IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 282 IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
277 283
278 if (skb->len > dst_mtu(skb->dst) && 284 skb->dev = dev;
279 !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) 285 skb->protocol = htons(ETH_P_IP);
280 return ip_fragment(skb, ip_finish_output); 286
281 else 287 return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
282 return ip_finish_output(skb); 288 ip_finish_output);
283} 289}
284 290
285int ip_queue_xmit(struct sk_buff *skb, int ipfragok) 291int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
@@ -411,7 +417,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
411 * single device frame, and queue such a frame for sending. 417 * single device frame, and queue such a frame for sending.
412 */ 418 */
413 419
414int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) 420static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
415{ 421{
416 struct iphdr *iph; 422 struct iphdr *iph;
417 int raw = 0; 423 int raw = 0;
@@ -420,7 +426,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
420 struct sk_buff *skb2; 426 struct sk_buff *skb2;
421 unsigned int mtu, hlen, left, len, ll_rs; 427 unsigned int mtu, hlen, left, len, ll_rs;
422 int offset; 428 int offset;
423 int not_last_frag; 429 __be16 not_last_frag;
424 struct rtable *rt = (struct rtable*)skb->dst; 430 struct rtable *rt = (struct rtable*)skb->dst;
425 int err = 0; 431 int err = 0;
426 432
@@ -445,6 +451,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
445 451
446 hlen = iph->ihl * 4; 452 hlen = iph->ihl * 4;
447 mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ 453 mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */
454 IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
448 455
449 /* When frag_list is given, use it. First, check its validity: 456 /* When frag_list is given, use it. First, check its validity:
450 * some transformers could create wrong frag_list or break existing 457 * some transformers could create wrong frag_list or break existing
@@ -1181,7 +1188,7 @@ int ip_push_pending_frames(struct sock *sk)
1181 struct ip_options *opt = NULL; 1188 struct ip_options *opt = NULL;
1182 struct rtable *rt = inet->cork.rt; 1189 struct rtable *rt = inet->cork.rt;
1183 struct iphdr *iph; 1190 struct iphdr *iph;
1184 int df = 0; 1191 __be16 df = 0;
1185 __u8 ttl; 1192 __u8 ttl;
1186 int err = 0; 1193 int err = 0;
1187 1194
@@ -1392,7 +1399,6 @@ void __init ip_init(void)
1392#endif 1399#endif
1393} 1400}
1394 1401
1395EXPORT_SYMBOL(ip_fragment);
1396EXPORT_SYMBOL(ip_generic_getfrag); 1402EXPORT_SYMBOL(ip_generic_getfrag);
1397EXPORT_SYMBOL(ip_queue_xmit); 1403EXPORT_SYMBOL(ip_queue_xmit);
1398EXPORT_SYMBOL(ip_send_check); 1404EXPORT_SYMBOL(ip_send_check);