ip_output.c (c0981b863a31a1891aa2719957983f4297770f87) | ip_output.c (73f156a6e8c1074ac6327e0abd1169e95eb66463) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * The Internet Protocol (IP) output module. 7 * 8 * Authors: Ross Biro --- 134 unchanged lines hidden (view full) --- 143 if (ip_dont_fragment(sk, &rt->dst)) 144 iph->frag_off = htons(IP_DF); 145 else 146 iph->frag_off = 0; 147 iph->ttl = ip_select_ttl(inet, &rt->dst); 148 iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); 149 iph->saddr = saddr; 150 iph->protocol = sk->sk_protocol; | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * The Internet Protocol (IP) output module. 7 * 8 * Authors: Ross Biro --- 134 unchanged lines hidden (view full) --- 143 if (ip_dont_fragment(sk, &rt->dst)) 144 iph->frag_off = htons(IP_DF); 145 else 146 iph->frag_off = 0; 147 iph->ttl = ip_select_ttl(inet, &rt->dst); 148 iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); 149 iph->saddr = saddr; 150 iph->protocol = sk->sk_protocol; |
151 ip_select_ident(skb, &rt->dst, sk); | 151 ip_select_ident(skb, sk); |
152 153 if (opt && opt->opt.optlen) { 154 iph->ihl += opt->opt.optlen>>2; 155 ip_options_build(skb, &opt->opt, daddr, rt, 0); 156 } 157 158 skb->priority = sk->sk_priority; 159 skb->mark = sk->sk_mark; --- 250 unchanged lines hidden (view full) --- 410 if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_uses_gateway) 411 goto no_route; 412 413 /* OK, we know where to send it, allocate and build IP header. */ 414 skb_push(skb, sizeof(struct iphdr) + (inet_opt ? inet_opt->opt.optlen : 0)); 415 skb_reset_network_header(skb); 416 iph = ip_hdr(skb); 417 *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); | 152 153 if (opt && opt->opt.optlen) { 154 iph->ihl += opt->opt.optlen>>2; 155 ip_options_build(skb, &opt->opt, daddr, rt, 0); 156 } 157 158 skb->priority = sk->sk_priority; 159 skb->mark = sk->sk_mark; --- 250 unchanged lines hidden (view full) --- 410 if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_uses_gateway) 411 goto no_route; 412 413 /* OK, we know where to send it, allocate and build IP header. */ 414 skb_push(skb, sizeof(struct iphdr) + (inet_opt ? inet_opt->opt.optlen : 0)); 415 skb_reset_network_header(skb); 416 iph = ip_hdr(skb); 417 *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); |
418 if (ip_dont_fragment(sk, &rt->dst) && !skb->local_df) | 418 if (ip_dont_fragment(sk, &rt->dst) && !skb->ignore_df) |
419 iph->frag_off = htons(IP_DF); 420 else 421 iph->frag_off = 0; 422 iph->ttl = ip_select_ttl(inet, &rt->dst); 423 iph->protocol = sk->sk_protocol; 424 ip_copy_addrs(iph, fl4); 425 426 /* Transport layer set skb->h.foo itself. */ 427 428 if (inet_opt && inet_opt->opt.optlen) { 429 iph->ihl += inet_opt->opt.optlen >> 2; 430 ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); 431 } 432 | 419 iph->frag_off = htons(IP_DF); 420 else 421 iph->frag_off = 0; 422 iph->ttl = ip_select_ttl(inet, &rt->dst); 423 iph->protocol = sk->sk_protocol; 424 ip_copy_addrs(iph, fl4); 425 426 /* Transport layer set skb->h.foo itself. */ 427 428 if (inet_opt && inet_opt->opt.optlen) { 429 iph->ihl += inet_opt->opt.optlen >> 2; 430 ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); 431 } 432 |
433 ip_select_ident_more(skb, &rt->dst, sk, 434 (skb_shinfo(skb)->gso_segs ?: 1) - 1); | 433 ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1); |
435 436 /* TODO : should we use skb->sk here instead of sk ? */ 437 skb->priority = sk->sk_priority; 438 skb->mark = sk->sk_mark; 439 440 res = ip_local_out(skb); 441 rcu_read_unlock(); 442 return res; --- 53 unchanged lines hidden (view full) --- 496 497 /* 498 * Point into the IP datagram header. 499 */ 500 501 iph = ip_hdr(skb); 502 503 mtu = ip_skb_dst_mtu(skb); | 434 435 /* TODO : should we use skb->sk here instead of sk ? */ 436 skb->priority = sk->sk_priority; 437 skb->mark = sk->sk_mark; 438 439 res = ip_local_out(skb); 440 rcu_read_unlock(); 441 return res; --- 53 unchanged lines hidden (view full) --- 495 496 /* 497 * Point into the IP datagram header. 498 */ 499 500 iph = ip_hdr(skb); 501 502 mtu = ip_skb_dst_mtu(skb); |
504 if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->local_df) || | 503 if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) || |
505 (IPCB(skb)->frag_max_size && 506 IPCB(skb)->frag_max_size > mtu))) { 507 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); 508 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, 509 htonl(mtu)); 510 kfree_skb(skb); 511 return -EMSGSIZE; 512 } --- 348 unchanged lines hidden (view full) --- 861 862 exthdrlen = !skb ? rt->dst.header_len : 0; 863 mtu = cork->fragsize; 864 865 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 866 867 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 868 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen; | 504 (IPCB(skb)->frag_max_size && 505 IPCB(skb)->frag_max_size > mtu))) { 506 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); 507 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, 508 htonl(mtu)); 509 kfree_skb(skb); 510 return -EMSGSIZE; 511 } --- 348 unchanged lines hidden (view full) --- 860 861 exthdrlen = !skb ? rt->dst.header_len : 0; 862 mtu = cork->fragsize; 863 864 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 865 866 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 867 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen; |
869 maxnonfragsize = ip_sk_local_df(sk) ? 0xFFFF : mtu; | 868 maxnonfragsize = ip_sk_ignore_df(sk) ? 0xFFFF : mtu; |
870 871 if (cork->length + length > maxnonfragsize - fragheaderlen) { 872 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, 873 mtu - (opt ? opt->optlen : 0)); 874 return -EMSGSIZE; 875 } 876 877 /* --- 306 unchanged lines hidden (view full) --- 1184 if (!(rt->dst.dev->features&NETIF_F_SG)) 1185 return -EOPNOTSUPP; 1186 1187 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 1188 mtu = cork->fragsize; 1189 1190 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 1191 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen; | 869 870 if (cork->length + length > maxnonfragsize - fragheaderlen) { 871 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, 872 mtu - (opt ? opt->optlen : 0)); 873 return -EMSGSIZE; 874 } 875 876 /* --- 306 unchanged lines hidden (view full) --- 1183 if (!(rt->dst.dev->features&NETIF_F_SG)) 1184 return -EOPNOTSUPP; 1185 1186 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 1187 mtu = cork->fragsize; 1188 1189 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 1190 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen; |
1192 maxnonfragsize = ip_sk_local_df(sk) ? 0xFFFF : mtu; | 1191 maxnonfragsize = ip_sk_ignore_df(sk) ? 0xFFFF : mtu; |
1193 1194 if (cork->length + size > maxnonfragsize - fragheaderlen) { 1195 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, 1196 mtu - (opt ? opt->optlen : 0)); 1197 return -EMSGSIZE; 1198 } 1199 1200 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) --- 144 unchanged lines hidden (view full) --- 1345 tmp_skb->destructor = NULL; 1346 tmp_skb->sk = NULL; 1347 } 1348 1349 /* Unless user demanded real pmtu discovery (IP_PMTUDISC_DO), we allow 1350 * to fragment the frame generated here. No matter, what transforms 1351 * how transforms change size of the packet, it will come out. 1352 */ | 1192 1193 if (cork->length + size > maxnonfragsize - fragheaderlen) { 1194 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, 1195 mtu - (opt ? opt->optlen : 0)); 1196 return -EMSGSIZE; 1197 } 1198 1199 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) --- 144 unchanged lines hidden (view full) --- 1344 tmp_skb->destructor = NULL; 1345 tmp_skb->sk = NULL; 1346 } 1347 1348 /* Unless user demanded real pmtu discovery (IP_PMTUDISC_DO), we allow 1349 * to fragment the frame generated here. No matter, what transforms 1350 * how transforms change size of the packet, it will come out. 1351 */ |
1353 skb->local_df = ip_sk_local_df(sk); | 1352 skb->ignore_df = ip_sk_ignore_df(sk); |
1354 1355 /* DF bit is set when we want to see DF on outgoing frames. | 1353 1354 /* DF bit is set when we want to see DF on outgoing frames. |
1356 * If local_df is set too, we still allow to fragment this frame | 1355 * If ignore_df is set too, we still allow to fragment this frame |
1357 * locally. */ 1358 if (inet->pmtudisc == IP_PMTUDISC_DO || 1359 inet->pmtudisc == IP_PMTUDISC_PROBE || 1360 (skb->len <= dst_mtu(&rt->dst) && 1361 ip_dont_fragment(sk, &rt->dst))) 1362 df = htons(IP_DF); 1363 1364 if (cork->flags & IPCORK_OPT) --- 9 unchanged lines hidden (view full) --- 1374 iph = ip_hdr(skb); 1375 iph->version = 4; 1376 iph->ihl = 5; 1377 iph->tos = (cork->tos != -1) ? cork->tos : inet->tos; 1378 iph->frag_off = df; 1379 iph->ttl = ttl; 1380 iph->protocol = sk->sk_protocol; 1381 ip_copy_addrs(iph, fl4); | 1356 * locally. */ 1357 if (inet->pmtudisc == IP_PMTUDISC_DO || 1358 inet->pmtudisc == IP_PMTUDISC_PROBE || 1359 (skb->len <= dst_mtu(&rt->dst) && 1360 ip_dont_fragment(sk, &rt->dst))) 1361 df = htons(IP_DF); 1362 1363 if (cork->flags & IPCORK_OPT) --- 9 unchanged lines hidden (view full) --- 1373 iph = ip_hdr(skb); 1374 iph->version = 4; 1375 iph->ihl = 5; 1376 iph->tos = (cork->tos != -1) ? cork->tos : inet->tos; 1377 iph->frag_off = df; 1378 iph->ttl = ttl; 1379 iph->protocol = sk->sk_protocol; 1380 ip_copy_addrs(iph, fl4); |
1382 ip_select_ident(skb, &rt->dst, sk); | 1381 ip_select_ident(skb, sk); |
1383 1384 if (opt) { 1385 iph->ihl += opt->optlen>>2; 1386 ip_options_build(skb, opt, cork->addr, rt, 0); 1387 } 1388 1389 skb->priority = (cork->tos != -1) ? cork->priority: sk->sk_priority; 1390 skb->mark = sk->sk_mark; --- 150 unchanged lines hidden (view full) --- 1541 1542 if (replyopts.opt.opt.optlen) { 1543 ipc.opt = &replyopts.opt; 1544 1545 if (replyopts.opt.opt.srr) 1546 daddr = replyopts.opt.opt.faddr; 1547 } 1548 | 1382 1383 if (opt) { 1384 iph->ihl += opt->optlen>>2; 1385 ip_options_build(skb, opt, cork->addr, rt, 0); 1386 } 1387 1388 skb->priority = (cork->tos != -1) ? cork->priority: sk->sk_priority; 1389 skb->mark = sk->sk_mark; --- 150 unchanged lines hidden (view full) --- 1540 1541 if (replyopts.opt.opt.optlen) { 1542 ipc.opt = &replyopts.opt; 1543 1544 if (replyopts.opt.opt.srr) 1545 daddr = replyopts.opt.opt.faddr; 1546 } 1547 |
1549 flowi4_init_output(&fl4, arg->bound_dev_if, 0, | 1548 flowi4_init_output(&fl4, arg->bound_dev_if, 1549 IP4_REPLY_MARK(net, skb->mark), |
1550 RT_TOS(arg->tos), 1551 RT_SCOPE_UNIVERSE, ip_hdr(skb)->protocol, 1552 ip_reply_arg_flowi_flags(arg), 1553 daddr, saddr, 1554 tcp_hdr(skb)->source, tcp_hdr(skb)->dest); 1555 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); 1556 rt = ip_route_output_key(net, &fl4); 1557 if (IS_ERR(rt)) --- 40 unchanged lines hidden --- | 1550 RT_TOS(arg->tos), 1551 RT_SCOPE_UNIVERSE, ip_hdr(skb)->protocol, 1552 ip_reply_arg_flowi_flags(arg), 1553 daddr, saddr, 1554 tcp_hdr(skb)->source, tcp_hdr(skb)->dest); 1555 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); 1556 rt = ip_route_output_key(net, &fl4); 1557 if (IS_ERR(rt)) --- 40 unchanged lines hidden --- |