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.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d1bcc9f21d4f..9a4a6c96cb0d 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -96,8 +96,8 @@ int __ip_local_out(struct sk_buff *skb)
96 96
97 iph->tot_len = htons(skb->len); 97 iph->tot_len = htons(skb->len);
98 ip_send_check(iph); 98 ip_send_check(iph);
99 return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, 99 return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL,
100 dst_output); 100 skb_dst(skb)->dev, dst_output);
101} 101}
102 102
103int ip_local_out(struct sk_buff *skb) 103int ip_local_out(struct sk_buff *skb)
@@ -272,8 +272,8 @@ int ip_mc_output(struct sk_buff *skb)
272 ) { 272 ) {
273 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); 273 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
274 if (newskb) 274 if (newskb)
275 NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, 275 NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,
276 NULL, newskb->dev, 276 newskb, NULL, newskb->dev,
277 ip_dev_loopback_xmit); 277 ip_dev_loopback_xmit);
278 } 278 }
279 279
@@ -288,12 +288,12 @@ int ip_mc_output(struct sk_buff *skb)
288 if (rt->rt_flags&RTCF_BROADCAST) { 288 if (rt->rt_flags&RTCF_BROADCAST) {
289 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); 289 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
290 if (newskb) 290 if (newskb)
291 NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, NULL, 291 NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb,
292 newskb->dev, ip_dev_loopback_xmit); 292 NULL, newskb->dev, ip_dev_loopback_xmit);
293 } 293 }
294 294
295 return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, skb->dev, 295 return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL,
296 ip_finish_output, 296 skb->dev, ip_finish_output,
297 !(IPCB(skb)->flags & IPSKB_REROUTED)); 297 !(IPCB(skb)->flags & IPSKB_REROUTED));
298} 298}
299 299
@@ -306,22 +306,24 @@ int ip_output(struct sk_buff *skb)
306 skb->dev = dev; 306 skb->dev = dev;
307 skb->protocol = htons(ETH_P_IP); 307 skb->protocol = htons(ETH_P_IP);
308 308
309 return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, dev, 309 return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, dev,
310 ip_finish_output, 310 ip_finish_output,
311 !(IPCB(skb)->flags & IPSKB_REROUTED)); 311 !(IPCB(skb)->flags & IPSKB_REROUTED));
312} 312}
313 313
314int ip_queue_xmit(struct sk_buff *skb, int ipfragok) 314int ip_queue_xmit(struct sk_buff *skb)
315{ 315{
316 struct sock *sk = skb->sk; 316 struct sock *sk = skb->sk;
317 struct inet_sock *inet = inet_sk(sk); 317 struct inet_sock *inet = inet_sk(sk);
318 struct ip_options *opt = inet->opt; 318 struct ip_options *opt = inet->opt;
319 struct rtable *rt; 319 struct rtable *rt;
320 struct iphdr *iph; 320 struct iphdr *iph;
321 int res;
321 322
322 /* Skip all of this if the packet is already routed, 323 /* Skip all of this if the packet is already routed,
323 * f.e. by something like SCTP. 324 * f.e. by something like SCTP.
324 */ 325 */
326 rcu_read_lock();
325 rt = skb_rtable(skb); 327 rt = skb_rtable(skb);
326 if (rt != NULL) 328 if (rt != NULL)
327 goto packet_routed; 329 goto packet_routed;
@@ -359,7 +361,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
359 } 361 }
360 sk_setup_caps(sk, &rt->u.dst); 362 sk_setup_caps(sk, &rt->u.dst);
361 } 363 }
362 skb_dst_set(skb, dst_clone(&rt->u.dst)); 364 skb_dst_set_noref(skb, &rt->u.dst);
363 365
364packet_routed: 366packet_routed:
365 if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) 367 if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
@@ -370,7 +372,7 @@ packet_routed:
370 skb_reset_network_header(skb); 372 skb_reset_network_header(skb);
371 iph = ip_hdr(skb); 373 iph = ip_hdr(skb);
372 *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); 374 *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
373 if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok) 375 if (ip_dont_fragment(sk, &rt->u.dst) && !skb->local_df)
374 iph->frag_off = htons(IP_DF); 376 iph->frag_off = htons(IP_DF);
375 else 377 else
376 iph->frag_off = 0; 378 iph->frag_off = 0;
@@ -391,9 +393,12 @@ packet_routed:
391 skb->priority = sk->sk_priority; 393 skb->priority = sk->sk_priority;
392 skb->mark = sk->sk_mark; 394 skb->mark = sk->sk_mark;
393 395
394 return ip_local_out(skb); 396 res = ip_local_out(skb);
397 rcu_read_unlock();
398 return res;
395 399
396no_route: 400no_route:
401 rcu_read_unlock();
397 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); 402 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
398 kfree_skb(skb); 403 kfree_skb(skb);
399 return -EHOSTUNREACH; 404 return -EHOSTUNREACH;
@@ -469,6 +474,10 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
469 474
470 hlen = iph->ihl * 4; 475 hlen = iph->ihl * 4;
471 mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ 476 mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */
477#ifdef CONFIG_BRIDGE_NETFILTER
478 if (skb->nf_bridge)
479 mtu -= nf_bridge_mtu_reduction(skb);
480#endif
472 IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE; 481 IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
473 482
474 /* When frag_list is given, use it. First, check its validity: 483 /* When frag_list is given, use it. First, check its validity: