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.c83
1 files changed, 41 insertions, 42 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 9a4a6c96cb0..6652bd9da67 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -89,6 +89,7 @@ __inline__ void ip_send_check(struct iphdr *iph)
89 iph->check = 0; 89 iph->check = 0;
90 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); 90 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
91} 91}
92EXPORT_SYMBOL(ip_send_check);
92 93
93int __ip_local_out(struct sk_buff *skb) 94int __ip_local_out(struct sk_buff *skb)
94{ 95{
@@ -151,15 +152,15 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
151 iph->version = 4; 152 iph->version = 4;
152 iph->ihl = 5; 153 iph->ihl = 5;
153 iph->tos = inet->tos; 154 iph->tos = inet->tos;
154 if (ip_dont_fragment(sk, &rt->u.dst)) 155 if (ip_dont_fragment(sk, &rt->dst))
155 iph->frag_off = htons(IP_DF); 156 iph->frag_off = htons(IP_DF);
156 else 157 else
157 iph->frag_off = 0; 158 iph->frag_off = 0;
158 iph->ttl = ip_select_ttl(inet, &rt->u.dst); 159 iph->ttl = ip_select_ttl(inet, &rt->dst);
159 iph->daddr = rt->rt_dst; 160 iph->daddr = rt->rt_dst;
160 iph->saddr = rt->rt_src; 161 iph->saddr = rt->rt_src;
161 iph->protocol = sk->sk_protocol; 162 iph->protocol = sk->sk_protocol;
162 ip_select_ident(iph, &rt->u.dst, sk); 163 ip_select_ident(iph, &rt->dst, sk);
163 164
164 if (opt && opt->optlen) { 165 if (opt && opt->optlen) {
165 iph->ihl += opt->optlen>>2; 166 iph->ihl += opt->optlen>>2;
@@ -172,7 +173,6 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
172 /* Send it out. */ 173 /* Send it out. */
173 return ip_local_out(skb); 174 return ip_local_out(skb);
174} 175}
175
176EXPORT_SYMBOL_GPL(ip_build_and_send_pkt); 176EXPORT_SYMBOL_GPL(ip_build_and_send_pkt);
177 177
178static inline int ip_finish_output2(struct sk_buff *skb) 178static inline int ip_finish_output2(struct sk_buff *skb)
@@ -240,7 +240,7 @@ int ip_mc_output(struct sk_buff *skb)
240{ 240{
241 struct sock *sk = skb->sk; 241 struct sock *sk = skb->sk;
242 struct rtable *rt = skb_rtable(skb); 242 struct rtable *rt = skb_rtable(skb);
243 struct net_device *dev = rt->u.dst.dev; 243 struct net_device *dev = rt->dst.dev;
244 244
245 /* 245 /*
246 * If the indicated interface is up and running, send the packet. 246 * If the indicated interface is up and running, send the packet.
@@ -359,9 +359,9 @@ int ip_queue_xmit(struct sk_buff *skb)
359 if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0)) 359 if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0))
360 goto no_route; 360 goto no_route;
361 } 361 }
362 sk_setup_caps(sk, &rt->u.dst); 362 sk_setup_caps(sk, &rt->dst);
363 } 363 }
364 skb_dst_set_noref(skb, &rt->u.dst); 364 skb_dst_set_noref(skb, &rt->dst);
365 365
366packet_routed: 366packet_routed:
367 if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) 367 if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
@@ -372,11 +372,11 @@ packet_routed:
372 skb_reset_network_header(skb); 372 skb_reset_network_header(skb);
373 iph = ip_hdr(skb); 373 iph = ip_hdr(skb);
374 *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); 374 *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
375 if (ip_dont_fragment(sk, &rt->u.dst) && !skb->local_df) 375 if (ip_dont_fragment(sk, &rt->dst) && !skb->local_df)
376 iph->frag_off = htons(IP_DF); 376 iph->frag_off = htons(IP_DF);
377 else 377 else
378 iph->frag_off = 0; 378 iph->frag_off = 0;
379 iph->ttl = ip_select_ttl(inet, &rt->u.dst); 379 iph->ttl = ip_select_ttl(inet, &rt->dst);
380 iph->protocol = sk->sk_protocol; 380 iph->protocol = sk->sk_protocol;
381 iph->saddr = rt->rt_src; 381 iph->saddr = rt->rt_src;
382 iph->daddr = rt->rt_dst; 382 iph->daddr = rt->rt_dst;
@@ -387,7 +387,7 @@ packet_routed:
387 ip_options_build(skb, opt, inet->inet_daddr, rt, 0); 387 ip_options_build(skb, opt, inet->inet_daddr, rt, 0);
388 } 388 }
389 389
390 ip_select_ident_more(iph, &rt->u.dst, sk, 390 ip_select_ident_more(iph, &rt->dst, sk,
391 (skb_shinfo(skb)->gso_segs ?: 1) - 1); 391 (skb_shinfo(skb)->gso_segs ?: 1) - 1);
392 392
393 skb->priority = sk->sk_priority; 393 skb->priority = sk->sk_priority;
@@ -403,6 +403,7 @@ no_route:
403 kfree_skb(skb); 403 kfree_skb(skb);
404 return -EHOSTUNREACH; 404 return -EHOSTUNREACH;
405} 405}
406EXPORT_SYMBOL(ip_queue_xmit);
406 407
407 408
408static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) 409static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
@@ -411,7 +412,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
411 to->priority = from->priority; 412 to->priority = from->priority;
412 to->protocol = from->protocol; 413 to->protocol = from->protocol;
413 skb_dst_drop(to); 414 skb_dst_drop(to);
414 skb_dst_set(to, dst_clone(skb_dst(from))); 415 skb_dst_copy(to, from);
415 to->dev = from->dev; 416 to->dev = from->dev;
416 to->mark = from->mark; 417 to->mark = from->mark;
417 418
@@ -442,7 +443,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
442int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 443int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
443{ 444{
444 struct iphdr *iph; 445 struct iphdr *iph;
445 int raw = 0;
446 int ptr; 446 int ptr;
447 struct net_device *dev; 447 struct net_device *dev;
448 struct sk_buff *skb2; 448 struct sk_buff *skb2;
@@ -452,7 +452,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
452 struct rtable *rt = skb_rtable(skb); 452 struct rtable *rt = skb_rtable(skb);
453 int err = 0; 453 int err = 0;
454 454
455 dev = rt->u.dst.dev; 455 dev = rt->dst.dev;
456 456
457 /* 457 /*
458 * Point into the IP datagram header. 458 * Point into the IP datagram header.
@@ -473,7 +473,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
473 */ 473 */
474 474
475 hlen = iph->ihl * 4; 475 hlen = iph->ihl * 4;
476 mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ 476 mtu = dst_mtu(&rt->dst) - hlen; /* Size of data space */
477#ifdef CONFIG_BRIDGE_NETFILTER 477#ifdef CONFIG_BRIDGE_NETFILTER
478 if (skb->nf_bridge) 478 if (skb->nf_bridge)
479 mtu -= nf_bridge_mtu_reduction(skb); 479 mtu -= nf_bridge_mtu_reduction(skb);
@@ -580,13 +580,13 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
580 580
581slow_path: 581slow_path:
582 left = skb->len - hlen; /* Space per frame */ 582 left = skb->len - hlen; /* Space per frame */
583 ptr = raw + hlen; /* Where to start from */ 583 ptr = hlen; /* Where to start from */
584 584
585 /* for bridged IP traffic encapsulated inside f.e. a vlan header, 585 /* for bridged IP traffic encapsulated inside f.e. a vlan header,
586 * we need to make room for the encapsulating header 586 * we need to make room for the encapsulating header
587 */ 587 */
588 pad = nf_bridge_pad(skb); 588 pad = nf_bridge_pad(skb);
589 ll_rs = LL_RESERVED_SPACE_EXTRA(rt->u.dst.dev, pad); 589 ll_rs = LL_RESERVED_SPACE_EXTRA(rt->dst.dev, pad);
590 mtu -= pad; 590 mtu -= pad;
591 591
592 /* 592 /*
@@ -697,7 +697,6 @@ fail:
697 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); 697 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
698 return err; 698 return err;
699} 699}
700
701EXPORT_SYMBOL(ip_fragment); 700EXPORT_SYMBOL(ip_fragment);
702 701
703int 702int
@@ -716,6 +715,7 @@ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk
716 } 715 }
717 return 0; 716 return 0;
718} 717}
718EXPORT_SYMBOL(ip_generic_getfrag);
719 719
720static inline __wsum 720static inline __wsum
721csum_page(struct page *page, int offset, int copy) 721csum_page(struct page *page, int offset, int copy)
@@ -833,13 +833,13 @@ int ip_append_data(struct sock *sk,
833 */ 833 */
834 *rtp = NULL; 834 *rtp = NULL;
835 inet->cork.fragsize = mtu = inet->pmtudisc == IP_PMTUDISC_PROBE ? 835 inet->cork.fragsize = mtu = inet->pmtudisc == IP_PMTUDISC_PROBE ?
836 rt->u.dst.dev->mtu : 836 rt->dst.dev->mtu :
837 dst_mtu(rt->u.dst.path); 837 dst_mtu(rt->dst.path);
838 inet->cork.dst = &rt->u.dst; 838 inet->cork.dst = &rt->dst;
839 inet->cork.length = 0; 839 inet->cork.length = 0;
840 sk->sk_sndmsg_page = NULL; 840 sk->sk_sndmsg_page = NULL;
841 sk->sk_sndmsg_off = 0; 841 sk->sk_sndmsg_off = 0;
842 if ((exthdrlen = rt->u.dst.header_len) != 0) { 842 if ((exthdrlen = rt->dst.header_len) != 0) {
843 length += exthdrlen; 843 length += exthdrlen;
844 transhdrlen += exthdrlen; 844 transhdrlen += exthdrlen;
845 } 845 }
@@ -852,7 +852,7 @@ int ip_append_data(struct sock *sk,
852 exthdrlen = 0; 852 exthdrlen = 0;
853 mtu = inet->cork.fragsize; 853 mtu = inet->cork.fragsize;
854 } 854 }
855 hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); 855 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
856 856
857 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 857 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
858 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen; 858 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
@@ -869,14 +869,16 @@ int ip_append_data(struct sock *sk,
869 */ 869 */
870 if (transhdrlen && 870 if (transhdrlen &&
871 length + fragheaderlen <= mtu && 871 length + fragheaderlen <= mtu &&
872 rt->u.dst.dev->features & NETIF_F_V4_CSUM && 872 rt->dst.dev->features & NETIF_F_V4_CSUM &&
873 !exthdrlen) 873 !exthdrlen)
874 csummode = CHECKSUM_PARTIAL; 874 csummode = CHECKSUM_PARTIAL;
875 875
876 skb = skb_peek_tail(&sk->sk_write_queue);
877
876 inet->cork.length += length; 878 inet->cork.length += length;
877 if (((length> mtu) || !skb_queue_empty(&sk->sk_write_queue)) && 879 if (((length > mtu) || (skb && skb_is_gso(skb))) &&
878 (sk->sk_protocol == IPPROTO_UDP) && 880 (sk->sk_protocol == IPPROTO_UDP) &&
879 (rt->u.dst.dev->features & NETIF_F_UFO)) { 881 (rt->dst.dev->features & NETIF_F_UFO)) {
880 err = ip_ufo_append_data(sk, getfrag, from, length, hh_len, 882 err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
881 fragheaderlen, transhdrlen, mtu, 883 fragheaderlen, transhdrlen, mtu,
882 flags); 884 flags);
@@ -892,7 +894,7 @@ int ip_append_data(struct sock *sk,
892 * adding appropriate IP header. 894 * adding appropriate IP header.
893 */ 895 */
894 896
895 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) 897 if (!skb)
896 goto alloc_new_skb; 898 goto alloc_new_skb;
897 899
898 while (length > 0) { 900 while (length > 0) {
@@ -924,7 +926,7 @@ alloc_new_skb:
924 fraglen = datalen + fragheaderlen; 926 fraglen = datalen + fragheaderlen;
925 927
926 if ((flags & MSG_MORE) && 928 if ((flags & MSG_MORE) &&
927 !(rt->u.dst.dev->features&NETIF_F_SG)) 929 !(rt->dst.dev->features&NETIF_F_SG))
928 alloclen = mtu; 930 alloclen = mtu;
929 else 931 else
930 alloclen = datalen + fragheaderlen; 932 alloclen = datalen + fragheaderlen;
@@ -935,7 +937,7 @@ alloc_new_skb:
935 * the last. 937 * the last.
936 */ 938 */
937 if (datalen == length + fraggap) 939 if (datalen == length + fraggap)
938 alloclen += rt->u.dst.trailer_len; 940 alloclen += rt->dst.trailer_len;
939 941
940 if (transhdrlen) { 942 if (transhdrlen) {
941 skb = sock_alloc_send_skb(sk, 943 skb = sock_alloc_send_skb(sk,
@@ -1008,7 +1010,7 @@ alloc_new_skb:
1008 if (copy > length) 1010 if (copy > length)
1009 copy = length; 1011 copy = length;
1010 1012
1011 if (!(rt->u.dst.dev->features&NETIF_F_SG)) { 1013 if (!(rt->dst.dev->features&NETIF_F_SG)) {
1012 unsigned int off; 1014 unsigned int off;
1013 1015
1014 off = skb->len; 1016 off = skb->len;
@@ -1103,10 +1105,10 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1103 if (inet->cork.flags & IPCORK_OPT) 1105 if (inet->cork.flags & IPCORK_OPT)
1104 opt = inet->cork.opt; 1106 opt = inet->cork.opt;
1105 1107
1106 if (!(rt->u.dst.dev->features&NETIF_F_SG)) 1108 if (!(rt->dst.dev->features&NETIF_F_SG))
1107 return -EOPNOTSUPP; 1109 return -EOPNOTSUPP;
1108 1110
1109 hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); 1111 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
1110 mtu = inet->cork.fragsize; 1112 mtu = inet->cork.fragsize;
1111 1113
1112 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 1114 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
@@ -1121,8 +1123,9 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1121 return -EINVAL; 1123 return -EINVAL;
1122 1124
1123 inet->cork.length += size; 1125 inet->cork.length += size;
1124 if ((sk->sk_protocol == IPPROTO_UDP) && 1126 if ((size + skb->len > mtu) &&
1125 (rt->u.dst.dev->features & NETIF_F_UFO)) { 1127 (sk->sk_protocol == IPPROTO_UDP) &&
1128 (rt->dst.dev->features & NETIF_F_UFO)) {
1126 skb_shinfo(skb)->gso_size = mtu - fragheaderlen; 1129 skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
1127 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 1130 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1128 } 1131 }
@@ -1274,8 +1277,8 @@ int ip_push_pending_frames(struct sock *sk)
1274 * If local_df is set too, we still allow to fragment this frame 1277 * If local_df is set too, we still allow to fragment this frame
1275 * locally. */ 1278 * locally. */
1276 if (inet->pmtudisc >= IP_PMTUDISC_DO || 1279 if (inet->pmtudisc >= IP_PMTUDISC_DO ||
1277 (skb->len <= dst_mtu(&rt->u.dst) && 1280 (skb->len <= dst_mtu(&rt->dst) &&
1278 ip_dont_fragment(sk, &rt->u.dst))) 1281 ip_dont_fragment(sk, &rt->dst)))
1279 df = htons(IP_DF); 1282 df = htons(IP_DF);
1280 1283
1281 if (inet->cork.flags & IPCORK_OPT) 1284 if (inet->cork.flags & IPCORK_OPT)
@@ -1284,7 +1287,7 @@ int ip_push_pending_frames(struct sock *sk)
1284 if (rt->rt_type == RTN_MULTICAST) 1287 if (rt->rt_type == RTN_MULTICAST)
1285 ttl = inet->mc_ttl; 1288 ttl = inet->mc_ttl;
1286 else 1289 else
1287 ttl = ip_select_ttl(inet, &rt->u.dst); 1290 ttl = ip_select_ttl(inet, &rt->dst);
1288 1291
1289 iph = (struct iphdr *)skb->data; 1292 iph = (struct iphdr *)skb->data;
1290 iph->version = 4; 1293 iph->version = 4;
@@ -1295,7 +1298,7 @@ int ip_push_pending_frames(struct sock *sk)
1295 } 1298 }
1296 iph->tos = inet->tos; 1299 iph->tos = inet->tos;
1297 iph->frag_off = df; 1300 iph->frag_off = df;
1298 ip_select_ident(iph, &rt->u.dst, sk); 1301 ip_select_ident(iph, &rt->dst, sk);
1299 iph->ttl = ttl; 1302 iph->ttl = ttl;
1300 iph->protocol = sk->sk_protocol; 1303 iph->protocol = sk->sk_protocol;
1301 iph->saddr = rt->rt_src; 1304 iph->saddr = rt->rt_src;
@@ -1308,7 +1311,7 @@ int ip_push_pending_frames(struct sock *sk)
1308 * on dst refcount 1311 * on dst refcount
1309 */ 1312 */
1310 inet->cork.dst = NULL; 1313 inet->cork.dst = NULL;
1311 skb_dst_set(skb, &rt->u.dst); 1314 skb_dst_set(skb, &rt->dst);
1312 1315
1313 if (iph->protocol == IPPROTO_ICMP) 1316 if (iph->protocol == IPPROTO_ICMP)
1314 icmp_out_count(net, ((struct icmphdr *) 1317 icmp_out_count(net, ((struct icmphdr *)
@@ -1445,7 +1448,3 @@ void __init ip_init(void)
1445 igmp_mc_proc_init(); 1448 igmp_mc_proc_init();
1446#endif 1449#endif
1447} 1450}
1448
1449EXPORT_SYMBOL(ip_generic_getfrag);
1450EXPORT_SYMBOL(ip_queue_xmit);
1451EXPORT_SYMBOL(ip_send_check);