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 ---