ip6_output.c (aa9e0de81b5b257f6dae48efe2ed5f255f066497) | ip6_output.c (09c2d251b70723650ba47e83571ff49281320f7c) |
---|---|
1/* 2 * IPv6 output functions 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on linux/net/ipv4/ip_output.c --- 191 unchanged lines hidden (view full) --- 200 /* 201 * Fill in the IPv6 header 202 */ 203 if (np) 204 hlimit = np->hop_limit; 205 if (hlimit < 0) 206 hlimit = ip6_dst_hoplimit(dst); 207 | 1/* 2 * IPv6 output functions 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on linux/net/ipv4/ip_output.c --- 191 unchanged lines hidden (view full) --- 200 /* 201 * Fill in the IPv6 header 202 */ 203 if (np) 204 hlimit = np->hop_limit; 205 if (hlimit < 0) 206 hlimit = ip6_dst_hoplimit(dst); 207 |
208 ip6_flow_hdr(hdr, tclass, fl6->flowlabel); | 208 ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel, 209 np->autoflowlabel)); |
209 210 hdr->payload_len = htons(seg_len); 211 hdr->nexthdr = proto; 212 hdr->hop_limit = hlimit; 213 214 hdr->saddr = fl6->saddr; 215 hdr->daddr = *first_hop; 216 --- 580 unchanged lines hidden (view full) --- 797 ipv6_select_ident(fh, rt); 798 frag_id = fh->identification; 799 } else 800 fh->identification = frag_id; 801 802 /* 803 * Copy a block of the IP datagram. 804 */ | 210 211 hdr->payload_len = htons(seg_len); 212 hdr->nexthdr = proto; 213 hdr->hop_limit = hlimit; 214 215 hdr->saddr = fl6->saddr; 216 hdr->daddr = *first_hop; 217 --- 580 unchanged lines hidden (view full) --- 798 ipv6_select_ident(fh, rt); 799 frag_id = fh->identification; 800 } else 801 fh->identification = frag_id; 802 803 /* 804 * Copy a block of the IP datagram. 805 */ |
805 if (skb_copy_bits(skb, ptr, skb_transport_header(frag), len)) 806 BUG(); | 806 BUG_ON(skb_copy_bits(skb, ptr, skb_transport_header(frag), 807 len)); |
807 left -= len; 808 809 fh->frag_off = htons(offset); 810 if (left > 0) 811 fh->frag_off |= htons(IP6_MF); 812 ipv6_hdr(frag)->payload_len = htons(frag->len - 813 sizeof(struct ipv6hdr)); 814 --- 336 unchanged lines hidden (view full) --- 1151 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu; 1152 int exthdrlen; 1153 int dst_exthdrlen; 1154 int hh_len; 1155 int copy; 1156 int err; 1157 int offset = 0; 1158 __u8 tx_flags = 0; | 808 left -= len; 809 810 fh->frag_off = htons(offset); 811 if (left > 0) 812 fh->frag_off |= htons(IP6_MF); 813 ipv6_hdr(frag)->payload_len = htons(frag->len - 814 sizeof(struct ipv6hdr)); 815 --- 336 unchanged lines hidden (view full) --- 1152 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu; 1153 int exthdrlen; 1154 int dst_exthdrlen; 1155 int hh_len; 1156 int copy; 1157 int err; 1158 int offset = 0; 1159 __u8 tx_flags = 0; |
1160 u32 tskey = 0; |
|
1159 1160 if (flags&MSG_PROBE) 1161 return 0; 1162 cork = &inet->cork.base; 1163 if (skb_queue_empty(&sk->sk_write_queue)) { 1164 /* 1165 * setup for corking 1166 */ --- 99 unchanged lines hidden (view full) --- 1266emsgsize: 1267 ipv6_local_error(sk, EMSGSIZE, fl6, 1268 mtu - headersize + 1269 sizeof(struct ipv6hdr)); 1270 return -EMSGSIZE; 1271 } 1272 } 1273 | 1161 1162 if (flags&MSG_PROBE) 1163 return 0; 1164 cork = &inet->cork.base; 1165 if (skb_queue_empty(&sk->sk_write_queue)) { 1166 /* 1167 * setup for corking 1168 */ --- 99 unchanged lines hidden (view full) --- 1268emsgsize: 1269 ipv6_local_error(sk, EMSGSIZE, fl6, 1270 mtu - headersize + 1271 sizeof(struct ipv6hdr)); 1272 return -EMSGSIZE; 1273 } 1274 } 1275 |
1274 /* For UDP, check if TX timestamp is enabled */ 1275 if (sk->sk_type == SOCK_DGRAM) | 1276 if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) { |
1276 sock_tx_timestamp(sk, &tx_flags); | 1277 sock_tx_timestamp(sk, &tx_flags); |
1278 if (tx_flags & SKBTX_ANY_SW_TSTAMP && 1279 sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) 1280 tskey = sk->sk_tskey++; 1281 } |
|
1277 1278 /* 1279 * Let's try using as much space as possible. 1280 * Use MTU if total length of the message fits into the MTU. 1281 * Otherwise, we need to reserve fragment header and 1282 * fragment alignment (= 8-15 octects, in total). 1283 * 1284 * Note that we may need to "move" the data from the tail of --- 91 unchanged lines hidden (view full) --- 1376 skb = NULL; 1377 if (atomic_read(&sk->sk_wmem_alloc) <= 1378 2 * sk->sk_sndbuf) 1379 skb = sock_wmalloc(sk, 1380 alloclen + hh_len, 1, 1381 sk->sk_allocation); 1382 if (unlikely(skb == NULL)) 1383 err = -ENOBUFS; | 1282 1283 /* 1284 * Let's try using as much space as possible. 1285 * Use MTU if total length of the message fits into the MTU. 1286 * Otherwise, we need to reserve fragment header and 1287 * fragment alignment (= 8-15 octects, in total). 1288 * 1289 * Note that we may need to "move" the data from the tail of --- 91 unchanged lines hidden (view full) --- 1381 skb = NULL; 1382 if (atomic_read(&sk->sk_wmem_alloc) <= 1383 2 * sk->sk_sndbuf) 1384 skb = sock_wmalloc(sk, 1385 alloclen + hh_len, 1, 1386 sk->sk_allocation); 1387 if (unlikely(skb == NULL)) 1388 err = -ENOBUFS; |
1384 else { 1385 /* Only the initial fragment 1386 * is time stamped. 1387 */ 1388 tx_flags = 0; 1389 } | |
1390 } 1391 if (skb == NULL) 1392 goto error; 1393 /* 1394 * Fill in the control structures 1395 */ 1396 skb->protocol = htons(ETH_P_IPV6); 1397 skb->ip_summed = CHECKSUM_NONE; 1398 skb->csum = 0; 1399 /* reserve for fragmentation and ipsec header */ 1400 skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + 1401 dst_exthdrlen); 1402 | 1389 } 1390 if (skb == NULL) 1391 goto error; 1392 /* 1393 * Fill in the control structures 1394 */ 1395 skb->protocol = htons(ETH_P_IPV6); 1396 skb->ip_summed = CHECKSUM_NONE; 1397 skb->csum = 0; 1398 /* reserve for fragmentation and ipsec header */ 1399 skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + 1400 dst_exthdrlen); 1401 |
1403 if (sk->sk_type == SOCK_DGRAM) 1404 skb_shinfo(skb)->tx_flags = tx_flags; | 1402 /* Only the initial fragment is time stamped */ 1403 skb_shinfo(skb)->tx_flags = tx_flags; 1404 tx_flags = 0; 1405 skb_shinfo(skb)->tskey = tskey; 1406 tskey = 0; |
1405 1406 /* 1407 * Find where to start putting bytes 1408 */ 1409 data = skb_put(skb, fraglen); 1410 skb_set_network_header(skb, exthdrlen); 1411 data += fragheaderlen; 1412 skb->transport_header = (skb->network_header + --- 153 unchanged lines hidden (view full) --- 1566 ipv6_push_frag_opts(skb, opt, &proto); 1567 if (opt && opt->opt_nflen) 1568 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst); 1569 1570 skb_push(skb, sizeof(struct ipv6hdr)); 1571 skb_reset_network_header(skb); 1572 hdr = ipv6_hdr(skb); 1573 | 1407 1408 /* 1409 * Find where to start putting bytes 1410 */ 1411 data = skb_put(skb, fraglen); 1412 skb_set_network_header(skb, exthdrlen); 1413 data += fragheaderlen; 1414 skb->transport_header = (skb->network_header + --- 153 unchanged lines hidden (view full) --- 1568 ipv6_push_frag_opts(skb, opt, &proto); 1569 if (opt && opt->opt_nflen) 1570 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst); 1571 1572 skb_push(skb, sizeof(struct ipv6hdr)); 1573 skb_reset_network_header(skb); 1574 hdr = ipv6_hdr(skb); 1575 |
1574 ip6_flow_hdr(hdr, np->cork.tclass, fl6->flowlabel); | 1576 ip6_flow_hdr(hdr, np->cork.tclass, 1577 ip6_make_flowlabel(net, skb, fl6->flowlabel, 1578 np->autoflowlabel)); |
1575 hdr->hop_limit = np->cork.hop_limit; 1576 hdr->nexthdr = proto; 1577 hdr->saddr = fl6->saddr; 1578 hdr->daddr = *final_dst; 1579 1580 skb->priority = sk->sk_priority; 1581 skb->mark = sk->sk_mark; 1582 --- 40 unchanged lines hidden --- | 1579 hdr->hop_limit = np->cork.hop_limit; 1580 hdr->nexthdr = proto; 1581 hdr->saddr = fl6->saddr; 1582 hdr->daddr = *final_dst; 1583 1584 skb->priority = sk->sk_priority; 1585 skb->mark = sk->sk_mark; 1586 --- 40 unchanged lines hidden --- |