ip_output.c (1f901d59a5489e4dc7fdd339808d89b89f35483e) ip_output.c (694aba690de062cf27b28a5e56e7a5a7185b0a1c)
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

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

871 int exthdrlen;
872 int mtu;
873 int copy;
874 int err;
875 int offset = 0;
876 unsigned int maxfraglen, fragheaderlen, maxnonfragsize;
877 int csummode = CHECKSUM_NONE;
878 struct rtable *rt = (struct rtable *)cork->dst;
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

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

871 int exthdrlen;
872 int mtu;
873 int copy;
874 int err;
875 int offset = 0;
876 unsigned int maxfraglen, fragheaderlen, maxnonfragsize;
877 int csummode = CHECKSUM_NONE;
878 struct rtable *rt = (struct rtable *)cork->dst;
879 unsigned int wmem_alloc_delta = 0;
879 u32 tskey = 0;
880
881 skb = skb_peek_tail(queue);
882
883 exthdrlen = !skb ? rt->dst.header_len : 0;
884 mtu = cork->fragsize;
885 if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
886 sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)

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

966 alloclen += rt->dst.trailer_len;
967
968 if (transhdrlen) {
969 skb = sock_alloc_send_skb(sk,
970 alloclen + hh_len + 15,
971 (flags & MSG_DONTWAIT), &err);
972 } else {
973 skb = NULL;
880 u32 tskey = 0;
881
882 skb = skb_peek_tail(queue);
883
884 exthdrlen = !skb ? rt->dst.header_len : 0;
885 mtu = cork->fragsize;
886 if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
887 sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)

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

967 alloclen += rt->dst.trailer_len;
968
969 if (transhdrlen) {
970 skb = sock_alloc_send_skb(sk,
971 alloclen + hh_len + 15,
972 (flags & MSG_DONTWAIT), &err);
973 } else {
974 skb = NULL;
974 if (refcount_read(&sk->sk_wmem_alloc) <=
975 if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <=
975 2 * sk->sk_sndbuf)
976 2 * sk->sk_sndbuf)
976 skb = sock_wmalloc(sk,
977 alloclen + hh_len + 15, 1,
978 sk->sk_allocation);
977 skb = alloc_skb(alloclen + hh_len + 15,
978 sk->sk_allocation);
979 if (unlikely(!skb))
980 err = -ENOBUFS;
981 }
982 if (!skb)
983 goto error;
984
985 /*
986 * Fill in the control structures

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

1028 csummode = CHECKSUM_NONE;
1029
1030 if ((flags & MSG_CONFIRM) && !skb_prev)
1031 skb_set_dst_pending_confirm(skb, 1);
1032
1033 /*
1034 * Put the packet on the pending queue.
1035 */
979 if (unlikely(!skb))
980 err = -ENOBUFS;
981 }
982 if (!skb)
983 goto error;
984
985 /*
986 * Fill in the control structures

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

1028 csummode = CHECKSUM_NONE;
1029
1030 if ((flags & MSG_CONFIRM) && !skb_prev)
1031 skb_set_dst_pending_confirm(skb, 1);
1032
1033 /*
1034 * Put the packet on the pending queue.
1035 */
1036 if (!skb->destructor) {
1037 skb->destructor = sock_wfree;
1038 skb->sk = sk;
1039 wmem_alloc_delta += skb->truesize;
1040 }
1036 __skb_queue_tail(queue, skb);
1037 continue;
1038 }
1039
1040 if (copy > length)
1041 copy = length;
1042
1043 if (!(rt->dst.dev->features&NETIF_F_SG)) {

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

1074 offset, copy, skb->len, skb) < 0)
1075 goto error_efault;
1076
1077 pfrag->offset += copy;
1078 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1079 skb->len += copy;
1080 skb->data_len += copy;
1081 skb->truesize += copy;
1041 __skb_queue_tail(queue, skb);
1042 continue;
1043 }
1044
1045 if (copy > length)
1046 copy = length;
1047
1048 if (!(rt->dst.dev->features&NETIF_F_SG)) {

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

1079 offset, copy, skb->len, skb) < 0)
1080 goto error_efault;
1081
1082 pfrag->offset += copy;
1083 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1084 skb->len += copy;
1085 skb->data_len += copy;
1086 skb->truesize += copy;
1082 refcount_add(copy, &sk->sk_wmem_alloc);
1087 wmem_alloc_delta += copy;
1083 }
1084 offset += copy;
1085 length -= copy;
1086 }
1087
1088 }
1089 offset += copy;
1090 length -= copy;
1091 }
1092
1093 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1088 return 0;
1089
1090error_efault:
1091 err = -EFAULT;
1092error:
1093 cork->length -= length;
1094 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
1094 return 0;
1095
1096error_efault:
1097 err = -EFAULT;
1098error:
1099 cork->length -= length;
1100 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
1101 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1095 return err;
1096}
1097
1098static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
1099 struct ipcm_cookie *ipc, struct rtable **rtp)
1100{
1101 struct ip_options_rcu *opt;
1102 struct rtable *rt;

--- 490 unchanged lines hidden ---
1102 return err;
1103}
1104
1105static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
1106 struct ipcm_cookie *ipc, struct rtable **rtp)
1107{
1108 struct ip_options_rcu *opt;
1109 struct rtable *rt;

--- 490 unchanged lines hidden ---