aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@linaro.org>2013-10-14 18:29:10 -0400
committerKevin Hilman <khilman@linaro.org>2013-10-14 18:29:24 -0400
commit7587b5965f57c1c4d6fd1377432a8473f5cd449a (patch)
tree85b7ced77656ac142369c6436df02b51d6d13527 /net/ipv6/ip6_output.c
parent6a9d10d529db69244baab335fb02caba3d6ebbc9 (diff)
parent8d71528343c69ce387bd5fdb4fd8dc2b9f69d97c (diff)
Merge tag 'omap-for-v3.13/quirk-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/dt
From Tony Lindgren: Changes needed to prepare for making omap3 device tree only: - Always build in board-generic, and add pdata quirks and auxdata support for it so we have all the pdata related quirks in the same place. - Merge of the drivers/pinctrl changes that are needed for PM to continue working on omap3 and also needed for other omaps eventually. The three pinctrl related patches have been acked by Linus Walleij and are pulled into both the pinctrl tree and this branch. - Few defconfig related changes for drivers needed. * tag 'omap-for-v3.13/quirk-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (523 commits) ARM: configs: omap2plus_defconfig: enable dwc3 and dependencies ARM: OMAP2+: Add WLAN modules and of_serial to omap2plus_defconfig ARM: OMAP2+: Run make savedefconfig on omap2plus_defconfig to shrink it ARM: OMAP2+: Add minimal 8250 support for GPMC ARM: OMAP2+: Use pdata quirks for wl12xx for omap3 evm and zoom3 ARM: OMAP: Move DT wake-up event handling over to use pinctrl-single-omap ARM: OMAP2+: Add support for auxdata pinctrl: single: Add support for auxdata pinctrl: single: Add support for wake-up interrupts pinctrl: single: Prepare for supporting SoC specific features ARM: OMAP2+: igep0020: use display init from dss-common ARM: OMAP2+: pdata-quirks: add legacy display init for IGEPv2 board +Linux 3.12-rc4 Signed-off-by: Kevin Hilman <khilman@linaro.org>
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c53
1 files changed, 22 insertions, 31 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 3a692d529163..a54c45ce4a48 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1015,6 +1015,8 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1015 * udp datagram 1015 * udp datagram
1016 */ 1016 */
1017 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { 1017 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
1018 struct frag_hdr fhdr;
1019
1018 skb = sock_alloc_send_skb(sk, 1020 skb = sock_alloc_send_skb(sk,
1019 hh_len + fragheaderlen + transhdrlen + 20, 1021 hh_len + fragheaderlen + transhdrlen + 20,
1020 (flags & MSG_DONTWAIT), &err); 1022 (flags & MSG_DONTWAIT), &err);
@@ -1036,12 +1038,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1036 skb->protocol = htons(ETH_P_IPV6); 1038 skb->protocol = htons(ETH_P_IPV6);
1037 skb->ip_summed = CHECKSUM_PARTIAL; 1039 skb->ip_summed = CHECKSUM_PARTIAL;
1038 skb->csum = 0; 1040 skb->csum = 0;
1039 }
1040
1041 err = skb_append_datato_frags(sk,skb, getfrag, from,
1042 (length - transhdrlen));
1043 if (!err) {
1044 struct frag_hdr fhdr;
1045 1041
1046 /* Specify the length of each IPv6 datagram fragment. 1042 /* Specify the length of each IPv6 datagram fragment.
1047 * It has to be a multiple of 8. 1043 * It has to be a multiple of 8.
@@ -1052,15 +1048,10 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1052 ipv6_select_ident(&fhdr, rt); 1048 ipv6_select_ident(&fhdr, rt);
1053 skb_shinfo(skb)->ip6_frag_id = fhdr.identification; 1049 skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
1054 __skb_queue_tail(&sk->sk_write_queue, skb); 1050 __skb_queue_tail(&sk->sk_write_queue, skb);
1055
1056 return 0;
1057 } 1051 }
1058 /* There is not enough support do UPD LSO,
1059 * so follow normal path
1060 */
1061 kfree_skb(skb);
1062 1052
1063 return err; 1053 return skb_append_datato_frags(sk, skb, getfrag, from,
1054 (length - transhdrlen));
1064} 1055}
1065 1056
1066static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, 1057static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
@@ -1227,27 +1218,27 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1227 * --yoshfuji 1218 * --yoshfuji
1228 */ 1219 */
1229 1220
1230 cork->length += length; 1221 if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP ||
1231 if (length > mtu) { 1222 sk->sk_protocol == IPPROTO_RAW)) {
1232 int proto = sk->sk_protocol; 1223 ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
1233 if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ 1224 return -EMSGSIZE;
1234 ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); 1225 }
1235 return -EMSGSIZE;
1236 }
1237
1238 if (proto == IPPROTO_UDP &&
1239 (rt->dst.dev->features & NETIF_F_UFO)) {
1240 1226
1241 err = ip6_ufo_append_data(sk, getfrag, from, length, 1227 skb = skb_peek_tail(&sk->sk_write_queue);
1242 hh_len, fragheaderlen, 1228 cork->length += length;
1243 transhdrlen, mtu, flags, rt); 1229 if (((length > mtu) ||
1244 if (err) 1230 (skb && skb_is_gso(skb))) &&
1245 goto error; 1231 (sk->sk_protocol == IPPROTO_UDP) &&
1246 return 0; 1232 (rt->dst.dev->features & NETIF_F_UFO)) {
1247 } 1233 err = ip6_ufo_append_data(sk, getfrag, from, length,
1234 hh_len, fragheaderlen,
1235 transhdrlen, mtu, flags, rt);
1236 if (err)
1237 goto error;
1238 return 0;
1248 } 1239 }
1249 1240
1250 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) 1241 if (!skb)
1251 goto alloc_new_skb; 1242 goto alloc_new_skb;
1252 1243
1253 while (length > 0) { 1244 while (length > 0) {