aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2005-09-07 21:19:03 -0400
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2005-09-07 21:19:03 -0400
commit41a1f8ea4fbfcdc4232f023732584aae2220de31 (patch)
tree9939686b354ced0b22d81efcbc12f5ed90372b09 /net/ipv6/ip6_output.c
parent333fad5364d6b457c8d837f7d05802d2aaf8a961 (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.c24
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
765int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), 772int 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));