diff options
author | David S. Miller <davem@davemloft.net> | 2014-01-06 17:37:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-06 17:37:45 -0500 |
commit | 56a4342dfe3145cd66f766adccb28fd9b571606d (patch) | |
tree | d1593764488ff8cbb0b83cb9ae35fd968bf81760 /net/ipv6/ip6_output.c | |
parent | 805c1f4aedaba1bc8d839e7c27b128083dd5c2f0 (diff) | |
parent | fe0d692bbc645786bce1a98439e548ae619269f5 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
ipv6 tunnel statistic bug fixes conflicting with consolidation into
generic sw per-cpu net stats.
qlogic conflict between queue counting bug fix and the addition
of multiple MAC address support.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 788c01a53593..d1de9560c421 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1188,11 +1188,35 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1188 | 1188 | ||
1189 | fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + | 1189 | fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + |
1190 | (opt ? opt->opt_nflen : 0); | 1190 | (opt ? opt->opt_nflen : 0); |
1191 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); | 1191 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - |
1192 | sizeof(struct frag_hdr); | ||
1192 | 1193 | ||
1193 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { | 1194 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { |
1194 | if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { | 1195 | unsigned int maxnonfragsize, headersize; |
1195 | ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen); | 1196 | |
1197 | headersize = sizeof(struct ipv6hdr) + | ||
1198 | (opt ? opt->tot_len : 0) + | ||
1199 | (dst_allfrag(&rt->dst) ? | ||
1200 | sizeof(struct frag_hdr) : 0) + | ||
1201 | rt->rt6i_nfheader_len; | ||
1202 | |||
1203 | maxnonfragsize = (np->pmtudisc >= IPV6_PMTUDISC_DO) ? | ||
1204 | mtu : sizeof(struct ipv6hdr) + IPV6_MAXPLEN; | ||
1205 | |||
1206 | /* dontfrag active */ | ||
1207 | if ((cork->length + length > mtu - headersize) && dontfrag && | ||
1208 | (sk->sk_protocol == IPPROTO_UDP || | ||
1209 | sk->sk_protocol == IPPROTO_RAW)) { | ||
1210 | ipv6_local_rxpmtu(sk, fl6, mtu - headersize + | ||
1211 | sizeof(struct ipv6hdr)); | ||
1212 | goto emsgsize; | ||
1213 | } | ||
1214 | |||
1215 | if (cork->length + length > maxnonfragsize - headersize) { | ||
1216 | emsgsize: | ||
1217 | ipv6_local_error(sk, EMSGSIZE, fl6, | ||
1218 | mtu - headersize + | ||
1219 | sizeof(struct ipv6hdr)); | ||
1196 | return -EMSGSIZE; | 1220 | return -EMSGSIZE; |
1197 | } | 1221 | } |
1198 | } | 1222 | } |
@@ -1217,12 +1241,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1217 | * --yoshfuji | 1241 | * --yoshfuji |
1218 | */ | 1242 | */ |
1219 | 1243 | ||
1220 | if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || | ||
1221 | sk->sk_protocol == IPPROTO_RAW)) { | ||
1222 | ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); | ||
1223 | return -EMSGSIZE; | ||
1224 | } | ||
1225 | |||
1226 | skb = skb_peek_tail(&sk->sk_write_queue); | 1244 | skb = skb_peek_tail(&sk->sk_write_queue); |
1227 | cork->length += length; | 1245 | cork->length += length; |
1228 | if (((length > mtu) || | 1246 | if (((length > mtu) || |