|
@@ -1150,6 +1150,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
{
|
|
{
|
|
struct inet_sock *inet = inet_sk(sk);
|
|
struct inet_sock *inet = inet_sk(sk);
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
|
|
|
+ struct inet_cork *cork;
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
unsigned int maxfraglen, fragheaderlen;
|
|
unsigned int maxfraglen, fragheaderlen;
|
|
int exthdrlen;
|
|
int exthdrlen;
|
|
@@ -1163,6 +1164,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
|
|
|
|
if (flags&MSG_PROBE)
|
|
if (flags&MSG_PROBE)
|
|
return 0;
|
|
return 0;
|
|
|
|
+ cork = &inet->cork.base;
|
|
if (skb_queue_empty(&sk->sk_write_queue)) {
|
|
if (skb_queue_empty(&sk->sk_write_queue)) {
|
|
/*
|
|
/*
|
|
* setup for corking
|
|
* setup for corking
|
|
@@ -1202,7 +1204,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
/* need source address above miyazawa*/
|
|
/* need source address above miyazawa*/
|
|
}
|
|
}
|
|
dst_hold(&rt->dst);
|
|
dst_hold(&rt->dst);
|
|
- inet->cork.dst = &rt->dst;
|
|
|
|
|
|
+ cork->dst = &rt->dst;
|
|
inet->cork.fl.u.ip6 = *fl6;
|
|
inet->cork.fl.u.ip6 = *fl6;
|
|
np->cork.hop_limit = hlimit;
|
|
np->cork.hop_limit = hlimit;
|
|
np->cork.tclass = tclass;
|
|
np->cork.tclass = tclass;
|
|
@@ -1212,10 +1214,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
if (np->frag_size)
|
|
if (np->frag_size)
|
|
mtu = np->frag_size;
|
|
mtu = np->frag_size;
|
|
}
|
|
}
|
|
- inet->cork.fragsize = mtu;
|
|
|
|
|
|
+ cork->fragsize = mtu;
|
|
if (dst_allfrag(rt->dst.path))
|
|
if (dst_allfrag(rt->dst.path))
|
|
- inet->cork.flags |= IPCORK_ALLFRAG;
|
|
|
|
- inet->cork.length = 0;
|
|
|
|
|
|
+ cork->flags |= IPCORK_ALLFRAG;
|
|
|
|
+ cork->length = 0;
|
|
sk->sk_sndmsg_page = NULL;
|
|
sk->sk_sndmsg_page = NULL;
|
|
sk->sk_sndmsg_off = 0;
|
|
sk->sk_sndmsg_off = 0;
|
|
exthdrlen = rt->dst.header_len + (opt ? opt->opt_flen : 0) -
|
|
exthdrlen = rt->dst.header_len + (opt ? opt->opt_flen : 0) -
|
|
@@ -1223,12 +1225,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
length += exthdrlen;
|
|
length += exthdrlen;
|
|
transhdrlen += exthdrlen;
|
|
transhdrlen += exthdrlen;
|
|
} else {
|
|
} else {
|
|
- rt = (struct rt6_info *)inet->cork.dst;
|
|
|
|
|
|
+ rt = (struct rt6_info *)cork->dst;
|
|
fl6 = &inet->cork.fl.u.ip6;
|
|
fl6 = &inet->cork.fl.u.ip6;
|
|
opt = np->cork.opt;
|
|
opt = np->cork.opt;
|
|
transhdrlen = 0;
|
|
transhdrlen = 0;
|
|
exthdrlen = 0;
|
|
exthdrlen = 0;
|
|
- mtu = inet->cork.fragsize;
|
|
|
|
|
|
+ mtu = cork->fragsize;
|
|
}
|
|
}
|
|
|
|
|
|
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
|
|
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
|
|
@@ -1238,7 +1240,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
|
|
maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
|
|
|
|
|
|
if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
|
|
if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
|
|
- if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
|
|
|
|
|
|
+ if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
|
|
ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen);
|
|
ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen);
|
|
return -EMSGSIZE;
|
|
return -EMSGSIZE;
|
|
}
|
|
}
|
|
@@ -1267,7 +1269,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
* --yoshfuji
|
|
* --yoshfuji
|
|
*/
|
|
*/
|
|
|
|
|
|
- inet->cork.length += length;
|
|
|
|
|
|
+ cork->length += length;
|
|
if (length > mtu) {
|
|
if (length > mtu) {
|
|
int proto = sk->sk_protocol;
|
|
int proto = sk->sk_protocol;
|
|
if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
|
|
if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
|
|
@@ -1292,7 +1294,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
|
|
|
|
while (length > 0) {
|
|
while (length > 0) {
|
|
/* Check if the remaining data fits into current packet. */
|
|
/* Check if the remaining data fits into current packet. */
|
|
- copy = (inet->cork.length <= mtu && !(inet->cork.flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len;
|
|
|
|
|
|
+ copy = (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len;
|
|
if (copy < length)
|
|
if (copy < length)
|
|
copy = maxfraglen - skb->len;
|
|
copy = maxfraglen - skb->len;
|
|
|
|
|
|
@@ -1317,7 +1319,7 @@ alloc_new_skb:
|
|
* we know we need more fragment(s).
|
|
* we know we need more fragment(s).
|
|
*/
|
|
*/
|
|
datalen = length + fraggap;
|
|
datalen = length + fraggap;
|
|
- if (datalen > (inet->cork.length <= mtu && !(inet->cork.flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
|
|
|
|
|
|
+ if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
|
|
datalen = maxfraglen - fragheaderlen;
|
|
datalen = maxfraglen - fragheaderlen;
|
|
|
|
|
|
fraglen = datalen + fragheaderlen;
|
|
fraglen = datalen + fragheaderlen;
|
|
@@ -1481,7 +1483,7 @@ alloc_new_skb:
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
error:
|
|
error:
|
|
- inet->cork.length -= length;
|
|
|
|
|
|
+ cork->length -= length;
|
|
IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
|
|
IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
@@ -1497,10 +1499,10 @@ static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
|
|
np->cork.opt = NULL;
|
|
np->cork.opt = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- if (inet->cork.dst) {
|
|
|
|
- dst_release(inet->cork.dst);
|
|
|
|
- inet->cork.dst = NULL;
|
|
|
|
- inet->cork.flags &= ~IPCORK_ALLFRAG;
|
|
|
|
|
|
+ if (inet->cork.base.dst) {
|
|
|
|
+ dst_release(inet->cork.base.dst);
|
|
|
|
+ inet->cork.base.dst = NULL;
|
|
|
|
+ inet->cork.base.flags &= ~IPCORK_ALLFRAG;
|
|
}
|
|
}
|
|
memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
|
|
memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
|
|
}
|
|
}
|
|
@@ -1515,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk)
|
|
struct net *net = sock_net(sk);
|
|
struct net *net = sock_net(sk);
|
|
struct ipv6hdr *hdr;
|
|
struct ipv6hdr *hdr;
|
|
struct ipv6_txoptions *opt = np->cork.opt;
|
|
struct ipv6_txoptions *opt = np->cork.opt;
|
|
- struct rt6_info *rt = (struct rt6_info *)inet->cork.dst;
|
|
|
|
|
|
+ struct rt6_info *rt = (struct rt6_info *)inet->cork.base.dst;
|
|
struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
|
|
struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
|
|
unsigned char proto = fl6->flowi6_proto;
|
|
unsigned char proto = fl6->flowi6_proto;
|
|
int err = 0;
|
|
int err = 0;
|