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

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

862 struct inet_cork *cork,
863 struct page_frag *pfrag,
864 int getfrag(void *from, char *to, int offset,
865 int len, int odd, struct sk_buff *skb),
866 void *from, int length, int transhdrlen,
867 unsigned int flags)
868{
869 struct inet_sock *inet = inet_sk(sk);
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

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

862 struct inet_cork *cork,
863 struct page_frag *pfrag,
864 int getfrag(void *from, char *to, int offset,
865 int len, int odd, struct sk_buff *skb),
866 void *from, int length, int transhdrlen,
867 unsigned int flags)
868{
869 struct inet_sock *inet = inet_sk(sk);
870 struct ubuf_info *uarg = NULL;
870 struct sk_buff *skb;
871
872 struct ip_options *opt = cork->opt;
873 int hh_len;
874 int exthdrlen;
875 int mtu;
876 int copy;
877 int err;

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

911 */
912 if (transhdrlen &&
913 length + fragheaderlen <= mtu &&
914 rt->dst.dev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM) &&
915 (!(flags & MSG_MORE) || cork->gso_size) &&
916 (!exthdrlen || (rt->dst.dev->features & NETIF_F_HW_ESP_TX_CSUM)))
917 csummode = CHECKSUM_PARTIAL;
918
871 struct sk_buff *skb;
872
873 struct ip_options *opt = cork->opt;
874 int hh_len;
875 int exthdrlen;
876 int mtu;
877 int copy;
878 int err;

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

912 */
913 if (transhdrlen &&
914 length + fragheaderlen <= mtu &&
915 rt->dst.dev->features & (NETIF_F_HW_CSUM | NETIF_F_IP_CSUM) &&
916 (!(flags & MSG_MORE) || cork->gso_size) &&
917 (!exthdrlen || (rt->dst.dev->features & NETIF_F_HW_ESP_TX_CSUM)))
918 csummode = CHECKSUM_PARTIAL;
919
920 if (flags & MSG_ZEROCOPY && length && sock_flag(sk, SOCK_ZEROCOPY)) {
921 uarg = sock_zerocopy_realloc(sk, length, skb_zcopy(skb));
922 if (!uarg)
923 return -ENOBUFS;
924 if (rt->dst.dev->features & NETIF_F_SG &&
925 csummode == CHECKSUM_PARTIAL) {
926 paged = true;
927 } else {
928 uarg->zerocopy = 0;
929 skb_zcopy_set(skb, uarg);
930 }
931 }
932
919 cork->length += length;
920
921 /* So, what's going on in the loop below?
922 *
923 * We use calculated fragment length to generate chained skb,
924 * each of segments is IP fragment ready for sending to network after
925 * adding appropriate IP header.
926 */

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

1001 skb->csum = 0;
1002 skb_reserve(skb, hh_len);
1003
1004 /* only the initial fragment is time stamped */
1005 skb_shinfo(skb)->tx_flags = cork->tx_flags;
1006 cork->tx_flags = 0;
1007 skb_shinfo(skb)->tskey = tskey;
1008 tskey = 0;
933 cork->length += length;
934
935 /* So, what's going on in the loop below?
936 *
937 * We use calculated fragment length to generate chained skb,
938 * each of segments is IP fragment ready for sending to network after
939 * adding appropriate IP header.
940 */

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

1015 skb->csum = 0;
1016 skb_reserve(skb, hh_len);
1017
1018 /* only the initial fragment is time stamped */
1019 skb_shinfo(skb)->tx_flags = cork->tx_flags;
1020 cork->tx_flags = 0;
1021 skb_shinfo(skb)->tskey = tskey;
1022 tskey = 0;
1023 skb_zcopy_set(skb, uarg);
1009
1010 /*
1011 * Find where to start putting bytes.
1012 */
1013 data = skb_put(skb, fraglen + exthdrlen - pagedlen);
1014 skb_set_network_header(skb, exthdrlen);
1015 skb->transport_header = (skb->network_header +
1016 fragheaderlen);

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

1063
1064 off = skb->len;
1065 if (getfrag(from, skb_put(skb, copy),
1066 offset, copy, off, skb) < 0) {
1067 __skb_trim(skb, off);
1068 err = -EFAULT;
1069 goto error;
1070 }
1024
1025 /*
1026 * Find where to start putting bytes.
1027 */
1028 data = skb_put(skb, fraglen + exthdrlen - pagedlen);
1029 skb_set_network_header(skb, exthdrlen);
1030 skb->transport_header = (skb->network_header +
1031 fragheaderlen);

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

1078
1079 off = skb->len;
1080 if (getfrag(from, skb_put(skb, copy),
1081 offset, copy, off, skb) < 0) {
1082 __skb_trim(skb, off);
1083 err = -EFAULT;
1084 goto error;
1085 }
1071 } else {
1086 } else if (!uarg || !uarg->zerocopy) {
1072 int i = skb_shinfo(skb)->nr_frags;
1073
1074 err = -ENOMEM;
1075 if (!sk_page_frag_refill(sk, pfrag))
1076 goto error;
1077
1078 if (!skb_can_coalesce(skb, i, pfrag->page,
1079 pfrag->offset)) {

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

1093 goto error_efault;
1094
1095 pfrag->offset += copy;
1096 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1097 skb->len += copy;
1098 skb->data_len += copy;
1099 skb->truesize += copy;
1100 wmem_alloc_delta += copy;
1087 int i = skb_shinfo(skb)->nr_frags;
1088
1089 err = -ENOMEM;
1090 if (!sk_page_frag_refill(sk, pfrag))
1091 goto error;
1092
1093 if (!skb_can_coalesce(skb, i, pfrag->page,
1094 pfrag->offset)) {

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

1108 goto error_efault;
1109
1110 pfrag->offset += copy;
1111 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1112 skb->len += copy;
1113 skb->data_len += copy;
1114 skb->truesize += copy;
1115 wmem_alloc_delta += copy;
1116 } else {
1117 err = skb_zerocopy_iter_dgram(skb, from, copy);
1118 if (err < 0)
1119 goto error;
1101 }
1102 offset += copy;
1103 length -= copy;
1104 }
1105
1106 if (wmem_alloc_delta)
1107 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1120 }
1121 offset += copy;
1122 length -= copy;
1123 }
1124
1125 if (wmem_alloc_delta)
1126 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1127 sock_zerocopy_put(uarg);
1108 return 0;
1109
1110error_efault:
1111 err = -EFAULT;
1112error:
1128 return 0;
1129
1130error_efault:
1131 err = -EFAULT;
1132error:
1133 sock_zerocopy_put_abort(uarg);
1113 cork->length -= length;
1114 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
1115 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1116 return err;
1117}
1118
1119static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
1120 struct ipcm_cookie *ipc, struct rtable **rtp)

--- 496 unchanged lines hidden ---
1134 cork->length -= length;
1135 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
1136 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1137 return err;
1138}
1139
1140static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
1141 struct ipcm_cookie *ipc, struct rtable **rtp)

--- 496 unchanged lines hidden ---