diff options
Diffstat (limited to 'net/ipv4/ip_output.c')
| -rw-r--r-- | net/ipv4/ip_output.c | 46 |
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 | ||
| 86 | int sysctl_ip_default_ttl = IPDEFTTL; | 87 | int sysctl_ip_default_ttl = IPDEFTTL; |
| 87 | 88 | ||
| 89 | static 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 | ||
| 203 | static inline int ip_finish_output(struct sk_buff *skb) | 206 | static 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 | ||
| 214 | int ip_mc_output(struct sk_buff *skb) | 220 | int 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 | ||
| 274 | int ip_output(struct sk_buff *skb) | 278 | int 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 | ||
| 285 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | 291 | int 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 | ||
| 414 | int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | 420 | static 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 | ||
| 1395 | EXPORT_SYMBOL(ip_fragment); | ||
| 1396 | EXPORT_SYMBOL(ip_generic_getfrag); | 1402 | EXPORT_SYMBOL(ip_generic_getfrag); |
| 1397 | EXPORT_SYMBOL(ip_queue_xmit); | 1403 | EXPORT_SYMBOL(ip_queue_xmit); |
| 1398 | EXPORT_SYMBOL(ip_send_check); | 1404 | EXPORT_SYMBOL(ip_send_check); |
