diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
| -rw-r--r-- | net/ipv6/ip6_output.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 01ef94f7c7f1..2f589f24c093 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -166,7 +166,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
| 166 | struct ipv6hdr *hdr; | 166 | struct ipv6hdr *hdr; |
| 167 | u8 proto = fl->proto; | 167 | u8 proto = fl->proto; |
| 168 | int seg_len = skb->len; | 168 | int seg_len = skb->len; |
| 169 | int hlimit; | 169 | int hlimit, tclass; |
| 170 | u32 mtu; | 170 | u32 mtu; |
| 171 | 171 | ||
| 172 | if (opt) { | 172 | if (opt) { |
| @@ -202,7 +202,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
| 202 | * Fill in the IPv6 header | 202 | * Fill in the IPv6 header |
| 203 | */ | 203 | */ |
| 204 | 204 | ||
| 205 | *(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel; | ||
| 206 | hlimit = -1; | 205 | hlimit = -1; |
| 207 | if (np) | 206 | if (np) |
| 208 | hlimit = np->hop_limit; | 207 | hlimit = np->hop_limit; |
| @@ -211,6 +210,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
| 211 | if (hlimit < 0) | 210 | if (hlimit < 0) |
| 212 | hlimit = ipv6_get_hoplimit(dst->dev); | 211 | hlimit = ipv6_get_hoplimit(dst->dev); |
| 213 | 212 | ||
| 213 | tclass = -1; | ||
| 214 | if (np) | ||
| 215 | tclass = np->tclass; | ||
| 216 | if (tclass < 0) | ||
| 217 | tclass = 0; | ||
| 218 | |||
| 219 | *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; | ||
| 220 | |||
| 214 | hdr->payload_len = htons(seg_len); | 221 | hdr->payload_len = htons(seg_len); |
| 215 | hdr->nexthdr = proto; | 222 | hdr->nexthdr = proto; |
| 216 | hdr->hop_limit = hlimit; | 223 | hdr->hop_limit = hlimit; |
| @@ -762,10 +769,11 @@ out_err_release: | |||
| 762 | return err; | 769 | return err; |
| 763 | } | 770 | } |
| 764 | 771 | ||
| 765 | int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), | 772 | int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
| 766 | void *from, int length, int transhdrlen, | 773 | int offset, int len, int odd, struct sk_buff *skb), |
| 767 | int hlimit, struct ipv6_txoptions *opt, struct flowi *fl, struct rt6_info *rt, | 774 | void *from, int length, int transhdrlen, |
| 768 | unsigned int flags) | 775 | int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, |
| 776 | struct rt6_info *rt, unsigned int flags) | ||
| 769 | { | 777 | { |
| 770 | struct inet_sock *inet = inet_sk(sk); | 778 | struct inet_sock *inet = inet_sk(sk); |
| 771 | struct ipv6_pinfo *np = inet6_sk(sk); | 779 | struct ipv6_pinfo *np = inet6_sk(sk); |
| @@ -803,6 +811,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse | |||
| 803 | np->cork.rt = rt; | 811 | np->cork.rt = rt; |
| 804 | inet->cork.fl = *fl; | 812 | inet->cork.fl = *fl; |
| 805 | np->cork.hop_limit = hlimit; | 813 | np->cork.hop_limit = hlimit; |
| 814 | np->cork.tclass = tclass; | ||
| 806 | inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path); | 815 | inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path); |
| 807 | if (dst_allfrag(rt->u.dst.path)) | 816 | if (dst_allfrag(rt->u.dst.path)) |
| 808 | inet->cork.flags |= IPCORK_ALLFRAG; | 817 | inet->cork.flags |= IPCORK_ALLFRAG; |
| @@ -1084,7 +1093,8 @@ int ip6_push_pending_frames(struct sock *sk) | |||
| 1084 | 1093 | ||
| 1085 | skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); | 1094 | skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); |
| 1086 | 1095 | ||
| 1087 | *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000); | 1096 | *(u32*)hdr = fl->fl6_flowlabel | |
| 1097 | htonl(0x60000000 | ((int)np->cork.tclass << 20)); | ||
| 1088 | 1098 | ||
| 1089 | if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) | 1099 | if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) |
| 1090 | hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); | 1100 | hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); |
