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.c78
1 files changed, 36 insertions, 42 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 041d41df1224..04b69896df5f 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,17 +443,16 @@ 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;
449 unsigned int mtu, hlen, left, len, ll_rs, pad; 449 unsigned int mtu, hlen, left, len, ll_rs;
450 int offset; 450 int offset;
451 __be16 not_last_frag; 451 __be16 not_last_frag;
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,14 +580,12 @@ 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 ll_rs = LL_RESERVED_SPACE_EXTRA(rt->dst.dev, nf_bridge_pad(skb));
589 ll_rs = LL_RESERVED_SPACE_EXTRA(rt->u.dst.dev, pad);
590 mtu -= pad;
591 589
592 /* 590 /*
593 * Fragment the datagram. 591 * Fragment the datagram.
@@ -697,7 +695,6 @@ fail:
697 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); 695 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
698 return err; 696 return err;
699} 697}
700
701EXPORT_SYMBOL(ip_fragment); 698EXPORT_SYMBOL(ip_fragment);
702 699
703int 700int
@@ -716,6 +713,7 @@ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk
716 } 713 }
717 return 0; 714 return 0;
718} 715}
716EXPORT_SYMBOL(ip_generic_getfrag);
719 717
720static inline __wsum 718static inline __wsum
721csum_page(struct page *page, int offset, int copy) 719csum_page(struct page *page, int offset, int copy)
@@ -833,13 +831,13 @@ int ip_append_data(struct sock *sk,
833 */ 831 */
834 *rtp = NULL; 832 *rtp = NULL;
835 inet->cork.fragsize = mtu = inet->pmtudisc == IP_PMTUDISC_PROBE ? 833 inet->cork.fragsize = mtu = inet->pmtudisc == IP_PMTUDISC_PROBE ?
836 rt->u.dst.dev->mtu : 834 rt->dst.dev->mtu :
837 dst_mtu(rt->u.dst.path); 835 dst_mtu(rt->dst.path);
838 inet->cork.dst = &rt->u.dst; 836 inet->cork.dst = &rt->dst;
839 inet->cork.length = 0; 837 inet->cork.length = 0;
840 sk->sk_sndmsg_page = NULL; 838 sk->sk_sndmsg_page = NULL;
841 sk->sk_sndmsg_off = 0; 839 sk->sk_sndmsg_off = 0;
842 if ((exthdrlen = rt->u.dst.header_len) != 0) { 840 if ((exthdrlen = rt->dst.header_len) != 0) {
843 length += exthdrlen; 841 length += exthdrlen;
844 transhdrlen += exthdrlen; 842 transhdrlen += exthdrlen;
845 } 843 }
@@ -852,7 +850,7 @@ int ip_append_data(struct sock *sk,
852 exthdrlen = 0; 850 exthdrlen = 0;
853 mtu = inet->cork.fragsize; 851 mtu = inet->cork.fragsize;
854 } 852 }
855 hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); 853 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
856 854
857 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 855 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
858 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen; 856 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
@@ -869,7 +867,7 @@ int ip_append_data(struct sock *sk,
869 */ 867 */
870 if (transhdrlen && 868 if (transhdrlen &&
871 length + fragheaderlen <= mtu && 869 length + fragheaderlen <= mtu &&
872 rt->u.dst.dev->features & NETIF_F_V4_CSUM && 870 rt->dst.dev->features & NETIF_F_V4_CSUM &&
873 !exthdrlen) 871 !exthdrlen)
874 csummode = CHECKSUM_PARTIAL; 872 csummode = CHECKSUM_PARTIAL;
875 873
@@ -878,7 +876,7 @@ int ip_append_data(struct sock *sk,
878 inet->cork.length += length; 876 inet->cork.length += length;
879 if (((length > mtu) || (skb && skb_is_gso(skb))) && 877 if (((length > mtu) || (skb && skb_is_gso(skb))) &&
880 (sk->sk_protocol == IPPROTO_UDP) && 878 (sk->sk_protocol == IPPROTO_UDP) &&
881 (rt->u.dst.dev->features & NETIF_F_UFO)) { 879 (rt->dst.dev->features & NETIF_F_UFO)) {
882 err = ip_ufo_append_data(sk, getfrag, from, length, hh_len, 880 err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
883 fragheaderlen, transhdrlen, mtu, 881 fragheaderlen, transhdrlen, mtu,
884 flags); 882 flags);
@@ -926,7 +924,7 @@ alloc_new_skb:
926 fraglen = datalen + fragheaderlen; 924 fraglen = datalen + fragheaderlen;
927 925
928 if ((flags & MSG_MORE) && 926 if ((flags & MSG_MORE) &&
929 !(rt->u.dst.dev->features&NETIF_F_SG)) 927 !(rt->dst.dev->features&NETIF_F_SG))
930 alloclen = mtu; 928 alloclen = mtu;
931 else 929 else
932 alloclen = datalen + fragheaderlen; 930 alloclen = datalen + fragheaderlen;
@@ -937,7 +935,7 @@ alloc_new_skb:
937 * the last. 935 * the last.
938 */ 936 */
939 if (datalen == length + fraggap) 937 if (datalen == length + fraggap)
940 alloclen += rt->u.dst.trailer_len; 938 alloclen += rt->dst.trailer_len;
941 939
942 if (transhdrlen) { 940 if (transhdrlen) {
943 skb = sock_alloc_send_skb(sk, 941 skb = sock_alloc_send_skb(sk,
@@ -1010,7 +1008,7 @@ alloc_new_skb:
1010 if (copy > length) 1008 if (copy > length)
1011 copy = length; 1009 copy = length;
1012 1010
1013 if (!(rt->u.dst.dev->features&NETIF_F_SG)) { 1011 if (!(rt->dst.dev->features&NETIF_F_SG)) {
1014 unsigned int off; 1012 unsigned int off;
1015 1013
1016 off = skb->len; 1014 off = skb->len;
@@ -1105,10 +1103,10 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1105 if (inet->cork.flags & IPCORK_OPT) 1103 if (inet->cork.flags & IPCORK_OPT)
1106 opt = inet->cork.opt; 1104 opt = inet->cork.opt;
1107 1105
1108 if (!(rt->u.dst.dev->features&NETIF_F_SG)) 1106 if (!(rt->dst.dev->features&NETIF_F_SG))
1109 return -EOPNOTSUPP; 1107 return -EOPNOTSUPP;
1110 1108
1111 hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); 1109 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
1112 mtu = inet->cork.fragsize; 1110 mtu = inet->cork.fragsize;
1113 1111
1114 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 1112 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
@@ -1125,7 +1123,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1125 inet->cork.length += size; 1123 inet->cork.length += size;
1126 if ((size + skb->len > mtu) && 1124 if ((size + skb->len > mtu) &&
1127 (sk->sk_protocol == IPPROTO_UDP) && 1125 (sk->sk_protocol == IPPROTO_UDP) &&
1128 (rt->u.dst.dev->features & NETIF_F_UFO)) { 1126 (rt->dst.dev->features & NETIF_F_UFO)) {
1129 skb_shinfo(skb)->gso_size = mtu - fragheaderlen; 1127 skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
1130 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 1128 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1131 } 1129 }
@@ -1277,8 +1275,8 @@ int ip_push_pending_frames(struct sock *sk)
1277 * If local_df is set too, we still allow to fragment this frame 1275 * If local_df is set too, we still allow to fragment this frame
1278 * locally. */ 1276 * locally. */
1279 if (inet->pmtudisc >= IP_PMTUDISC_DO || 1277 if (inet->pmtudisc >= IP_PMTUDISC_DO ||
1280 (skb->len <= dst_mtu(&rt->u.dst) && 1278 (skb->len <= dst_mtu(&rt->dst) &&
1281 ip_dont_fragment(sk, &rt->u.dst))) 1279 ip_dont_fragment(sk, &rt->dst)))
1282 df = htons(IP_DF); 1280 df = htons(IP_DF);
1283 1281
1284 if (inet->cork.flags & IPCORK_OPT) 1282 if (inet->cork.flags & IPCORK_OPT)
@@ -1287,7 +1285,7 @@ int ip_push_pending_frames(struct sock *sk)
1287 if (rt->rt_type == RTN_MULTICAST) 1285 if (rt->rt_type == RTN_MULTICAST)
1288 ttl = inet->mc_ttl; 1286 ttl = inet->mc_ttl;
1289 else 1287 else
1290 ttl = ip_select_ttl(inet, &rt->u.dst); 1288 ttl = ip_select_ttl(inet, &rt->dst);
1291 1289
1292 iph = (struct iphdr *)skb->data; 1290 iph = (struct iphdr *)skb->data;
1293 iph->version = 4; 1291 iph->version = 4;
@@ -1298,7 +1296,7 @@ int ip_push_pending_frames(struct sock *sk)
1298 } 1296 }
1299 iph->tos = inet->tos; 1297 iph->tos = inet->tos;
1300 iph->frag_off = df; 1298 iph->frag_off = df;
1301 ip_select_ident(iph, &rt->u.dst, sk); 1299 ip_select_ident(iph, &rt->dst, sk);
1302 iph->ttl = ttl; 1300 iph->ttl = ttl;
1303 iph->protocol = sk->sk_protocol; 1301 iph->protocol = sk->sk_protocol;
1304 iph->saddr = rt->rt_src; 1302 iph->saddr = rt->rt_src;
@@ -1311,7 +1309,7 @@ int ip_push_pending_frames(struct sock *sk)
1311 * on dst refcount 1309 * on dst refcount
1312 */ 1310 */
1313 inet->cork.dst = NULL; 1311 inet->cork.dst = NULL;
1314 skb_dst_set(skb, &rt->u.dst); 1312 skb_dst_set(skb, &rt->dst);
1315 1313
1316 if (iph->protocol == IPPROTO_ICMP) 1314 if (iph->protocol == IPPROTO_ICMP)
1317 icmp_out_count(net, ((struct icmphdr *) 1315 icmp_out_count(net, ((struct icmphdr *)
@@ -1448,7 +1446,3 @@ void __init ip_init(void)
1448 igmp_mc_proc_init(); 1446 igmp_mc_proc_init();
1449#endif 1447#endif
1450} 1448}
1451
1452EXPORT_SYMBOL(ip_generic_getfrag);
1453EXPORT_SYMBOL(ip_queue_xmit);
1454EXPORT_SYMBOL(ip_send_check);