|
@@ -494,6 +494,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
|
|
|
struct net_device *dev;
|
|
|
struct sk_buff *frag;
|
|
|
struct rt6_info *rt = (struct rt6_info*)skb->dst;
|
|
|
+ struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
|
|
|
struct ipv6hdr *tmp_hdr;
|
|
|
struct frag_hdr *fh;
|
|
|
unsigned int mtu, hlen, left, len;
|
|
@@ -505,7 +506,12 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
|
|
|
hlen = ip6_find_1stfragopt(skb, &prevhdr);
|
|
|
nexthdr = *prevhdr;
|
|
|
|
|
|
- mtu = dst_mtu(&rt->u.dst) - hlen - sizeof(struct frag_hdr);
|
|
|
+ mtu = dst_mtu(&rt->u.dst);
|
|
|
+ if (np && np->frag_size < mtu) {
|
|
|
+ if (np->frag_size)
|
|
|
+ mtu = np->frag_size;
|
|
|
+ }
|
|
|
+ mtu -= hlen + sizeof(struct frag_hdr);
|
|
|
|
|
|
if (skb_shinfo(skb)->frag_list) {
|
|
|
int first_len = skb_pagelen(skb);
|
|
@@ -882,7 +888,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|
|
inet->cork.fl = *fl;
|
|
|
np->cork.hop_limit = hlimit;
|
|
|
np->cork.tclass = tclass;
|
|
|
- inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path);
|
|
|
+ mtu = dst_mtu(rt->u.dst.path);
|
|
|
+ if (np && np->frag_size < mtu) {
|
|
|
+ if (np->frag_size)
|
|
|
+ mtu = np->frag_size;
|
|
|
+ }
|
|
|
+ inet->cork.fragsize = mtu;
|
|
|
if (dst_allfrag(rt->u.dst.path))
|
|
|
inet->cork.flags |= IPCORK_ALLFRAG;
|
|
|
inet->cork.length = 0;
|