diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2005-09-07 21:19:03 -0400 |
---|---|---|
committer | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2005-09-07 21:19:03 -0400 |
commit | 41a1f8ea4fbfcdc4232f023732584aae2220de31 (patch) | |
tree | 9939686b354ced0b22d81efcbc12f5ed90372b09 /net/ipv6/ip6_output.c | |
parent | 333fad5364d6b457c8d837f7d05802d2aaf8a961 (diff) |
[IPV6]: Support IPV6_{RECV,}TCLASS socket options / ancillary data.
Based on patch from David L Stevens <dlstevens@us.ibm.com>
Signed-off-by: David L Stevens <dlstevens@us.ibm.com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
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)); |