ip6_output.c (989a4222c13a3e148772730d362fceb0727852f5) ip6_output.c (b5947e5d1e710c35ea281247bd27e6975250285c)
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

--- 1231 unchanged lines hidden (view full) ---

1240 struct page_frag *pfrag,
1241 int getfrag(void *from, char *to, int offset,
1242 int len, int odd, struct sk_buff *skb),
1243 void *from, int length, int transhdrlen,
1244 unsigned int flags, struct ipcm6_cookie *ipc6)
1245{
1246 struct sk_buff *skb, *skb_prev = NULL;
1247 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
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

--- 1231 unchanged lines hidden (view full) ---

1240 struct page_frag *pfrag,
1241 int getfrag(void *from, char *to, int offset,
1242 int len, int odd, struct sk_buff *skb),
1243 void *from, int length, int transhdrlen,
1244 unsigned int flags, struct ipcm6_cookie *ipc6)
1245{
1246 struct sk_buff *skb, *skb_prev = NULL;
1247 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
1248 struct ubuf_info *uarg = NULL;
1248 int exthdrlen = 0;
1249 int dst_exthdrlen = 0;
1250 int hh_len;
1251 int copy;
1252 int err;
1253 int offset = 0;
1254 u32 tskey = 0;
1255 struct rt6_info *rt = (struct rt6_info *)cork->dst;

--- 61 unchanged lines hidden (view full) ---

1317 */
1318 if (transhdrlen && sk->sk_protocol == IPPROTO_UDP &&
1319 headersize == sizeof(struct ipv6hdr) &&
1320 length <= mtu - headersize &&
1321 (!(flags & MSG_MORE) || cork->gso_size) &&
1322 rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
1323 csummode = CHECKSUM_PARTIAL;
1324
1249 int exthdrlen = 0;
1250 int dst_exthdrlen = 0;
1251 int hh_len;
1252 int copy;
1253 int err;
1254 int offset = 0;
1255 u32 tskey = 0;
1256 struct rt6_info *rt = (struct rt6_info *)cork->dst;

--- 61 unchanged lines hidden (view full) ---

1318 */
1319 if (transhdrlen && sk->sk_protocol == IPPROTO_UDP &&
1320 headersize == sizeof(struct ipv6hdr) &&
1321 length <= mtu - headersize &&
1322 (!(flags & MSG_MORE) || cork->gso_size) &&
1323 rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
1324 csummode = CHECKSUM_PARTIAL;
1325
1326 if (flags & MSG_ZEROCOPY && length && sock_flag(sk, SOCK_ZEROCOPY)) {
1327 uarg = sock_zerocopy_realloc(sk, length, skb_zcopy(skb));
1328 if (!uarg)
1329 return -ENOBUFS;
1330 if (rt->dst.dev->features & NETIF_F_SG &&
1331 csummode == CHECKSUM_PARTIAL) {
1332 paged = true;
1333 } else {
1334 uarg->zerocopy = 0;
1335 skb_zcopy_set(skb, uarg);
1336 }
1337 }
1338
1325 /*
1326 * Let's try using as much space as possible.
1327 * Use MTU if total length of the message fits into the MTU.
1328 * Otherwise, we need to reserve fragment header and
1329 * fragment alignment (= 8-15 octects, in total).
1330 *
1331 * Note that we may need to "move" the data from the tail of
1332 * of the buffer to the new fragment when we split

--- 107 unchanged lines hidden (view full) ---

1440 skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
1441 dst_exthdrlen);
1442
1443 /* Only the initial fragment is time stamped */
1444 skb_shinfo(skb)->tx_flags = cork->tx_flags;
1445 cork->tx_flags = 0;
1446 skb_shinfo(skb)->tskey = tskey;
1447 tskey = 0;
1339 /*
1340 * Let's try using as much space as possible.
1341 * Use MTU if total length of the message fits into the MTU.
1342 * Otherwise, we need to reserve fragment header and
1343 * fragment alignment (= 8-15 octects, in total).
1344 *
1345 * Note that we may need to "move" the data from the tail of
1346 * of the buffer to the new fragment when we split

--- 107 unchanged lines hidden (view full) ---

1454 skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
1455 dst_exthdrlen);
1456
1457 /* Only the initial fragment is time stamped */
1458 skb_shinfo(skb)->tx_flags = cork->tx_flags;
1459 cork->tx_flags = 0;
1460 skb_shinfo(skb)->tskey = tskey;
1461 tskey = 0;
1462 skb_zcopy_set(skb, uarg);
1448
1449 /*
1450 * Find where to start putting bytes
1451 */
1452 data = skb_put(skb, fraglen - pagedlen);
1453 skb_set_network_header(skb, exthdrlen);
1454 data += fragheaderlen;
1455 skb->transport_header = (skb->network_header +

--- 45 unchanged lines hidden (view full) ---

1501
1502 off = skb->len;
1503 if (getfrag(from, skb_put(skb, copy),
1504 offset, copy, off, skb) < 0) {
1505 __skb_trim(skb, off);
1506 err = -EFAULT;
1507 goto error;
1508 }
1463
1464 /*
1465 * Find where to start putting bytes
1466 */
1467 data = skb_put(skb, fraglen - pagedlen);
1468 skb_set_network_header(skb, exthdrlen);
1469 data += fragheaderlen;
1470 skb->transport_header = (skb->network_header +

--- 45 unchanged lines hidden (view full) ---

1516
1517 off = skb->len;
1518 if (getfrag(from, skb_put(skb, copy),
1519 offset, copy, off, skb) < 0) {
1520 __skb_trim(skb, off);
1521 err = -EFAULT;
1522 goto error;
1523 }
1509 } else {
1524 } else if (!uarg || !uarg->zerocopy) {
1510 int i = skb_shinfo(skb)->nr_frags;
1511
1512 err = -ENOMEM;
1513 if (!sk_page_frag_refill(sk, pfrag))
1514 goto error;
1515
1516 if (!skb_can_coalesce(skb, i, pfrag->page,
1517 pfrag->offset)) {

--- 13 unchanged lines hidden (view full) ---

1531 goto error_efault;
1532
1533 pfrag->offset += copy;
1534 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1535 skb->len += copy;
1536 skb->data_len += copy;
1537 skb->truesize += copy;
1538 wmem_alloc_delta += copy;
1525 int i = skb_shinfo(skb)->nr_frags;
1526
1527 err = -ENOMEM;
1528 if (!sk_page_frag_refill(sk, pfrag))
1529 goto error;
1530
1531 if (!skb_can_coalesce(skb, i, pfrag->page,
1532 pfrag->offset)) {

--- 13 unchanged lines hidden (view full) ---

1546 goto error_efault;
1547
1548 pfrag->offset += copy;
1549 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1550 skb->len += copy;
1551 skb->data_len += copy;
1552 skb->truesize += copy;
1553 wmem_alloc_delta += copy;
1554 } else {
1555 err = skb_zerocopy_iter_dgram(skb, from, copy);
1556 if (err < 0)
1557 goto error;
1539 }
1540 offset += copy;
1541 length -= copy;
1542 }
1543
1544 if (wmem_alloc_delta)
1545 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1558 }
1559 offset += copy;
1560 length -= copy;
1561 }
1562
1563 if (wmem_alloc_delta)
1564 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1565 sock_zerocopy_put(uarg);
1546 return 0;
1547
1548error_efault:
1549 err = -EFAULT;
1550error:
1566 return 0;
1567
1568error_efault:
1569 err = -EFAULT;
1570error:
1571 sock_zerocopy_put_abort(uarg);
1551 cork->length -= length;
1552 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1553 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1554 return err;
1555}
1556
1557int ip6_append_data(struct sock *sk,
1558 int getfrag(void *from, char *to, int offset, int len,

--- 227 unchanged lines hidden ---
1572 cork->length -= length;
1573 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1574 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1575 return err;
1576}
1577
1578int ip6_append_data(struct sock *sk,
1579 int getfrag(void *from, char *to, int offset, int len,

--- 227 unchanged lines hidden ---