aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-08 18:52:11 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-08 18:52:11 -0400
commit27e2df2228712af43e657b9768828448c64ba424 (patch)
tree1c86905fd366e8af66ea75bfd34a50f7084e0869 /net
parentc0d6f9663b30a09ed725229b2d50391268c8538e (diff)
parente104411b82f5c4d19752c335492036abdbf5880d (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net')
-rw-r--r--net/ax25/ax25_addr.c27
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c24
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c5
-rw-r--r--net/ipv4/route.c29
-rw-r--r--net/ipv4/tcp_output.c2
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv6/datagram.c139
-rw-r--r--net/ipv6/exthdrs.c116
-rw-r--r--net/ipv6/icmp.c20
-rw-r--r--net/ipv6/ip6_flowlabel.c14
-rw-r--r--net/ipv6/ip6_output.c24
-rw-r--r--net/ipv6/ip6_tunnel.c7
-rw-r--r--net/ipv6/ipv6_sockglue.c186
-rw-r--r--net/ipv6/ndisc.c16
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c5
-rw-r--r--net/ipv6/raw.c21
-rw-r--r--net/ipv6/reassembly.c9
-rw-r--r--net/ipv6/tcp_ipv6.c36
-rw-r--r--net/ipv6/udp.c25
-rw-r--r--net/rose/rose_subr.c4
-rw-r--r--net/xfrm/xfrm_policy.c8
21 files changed, 557 insertions, 162 deletions
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index dca179daf415..0164a155b8c4 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -67,37 +67,34 @@ char *ax2asc(char *buf, ax25_address *a)
67/* 67/*
68 * ascii -> ax25 conversion 68 * ascii -> ax25 conversion
69 */ 69 */
70ax25_address *asc2ax(char *callsign) 70void asc2ax(ax25_address *addr, char *callsign)
71{ 71{
72 static ax25_address addr;
73 char *s; 72 char *s;
74 int n; 73 int n;
75 74
76 for (s = callsign, n = 0; n < 6; n++) { 75 for (s = callsign, n = 0; n < 6; n++) {
77 if (*s != '\0' && *s != '-') 76 if (*s != '\0' && *s != '-')
78 addr.ax25_call[n] = *s++; 77 addr->ax25_call[n] = *s++;
79 else 78 else
80 addr.ax25_call[n] = ' '; 79 addr->ax25_call[n] = ' ';
81 addr.ax25_call[n] <<= 1; 80 addr->ax25_call[n] <<= 1;
82 addr.ax25_call[n] &= 0xFE; 81 addr->ax25_call[n] &= 0xFE;
83 } 82 }
84 83
85 if (*s++ == '\0') { 84 if (*s++ == '\0') {
86 addr.ax25_call[6] = 0x00; 85 addr->ax25_call[6] = 0x00;
87 return &addr; 86 return;
88 } 87 }
89 88
90 addr.ax25_call[6] = *s++ - '0'; 89 addr->ax25_call[6] = *s++ - '0';
91 90
92 if (*s != '\0') { 91 if (*s != '\0') {
93 addr.ax25_call[6] *= 10; 92 addr->ax25_call[6] *= 10;
94 addr.ax25_call[6] += *s++ - '0'; 93 addr->ax25_call[6] += *s++ - '0';
95 } 94 }
96 95
97 addr.ax25_call[6] <<= 1; 96 addr->ax25_call[6] <<= 1;
98 addr.ax25_call[6] &= 0x1E; 97 addr->ax25_call[6] &= 0x1E;
99
100 return &addr;
101} 98}
102 99
103/* 100/*
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index 2b5cf9c51309..bb7246683b74 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -104,12 +104,28 @@ out:
104static struct ip_conntrack_helper helper = { 104static struct ip_conntrack_helper helper = {
105 .name = "netbios-ns", 105 .name = "netbios-ns",
106 .tuple = { 106 .tuple = {
107 .src.u.udp.port = __constant_htons(137), 107 .src = {
108 .dst.protonum = IPPROTO_UDP, 108 .u = {
109 .udp = {
110 .port = __constant_htons(137),
111 }
112 }
113 },
114 .dst = {
115 .protonum = IPPROTO_UDP,
116 },
109 }, 117 },
110 .mask = { 118 .mask = {
111 .src.u.udp.port = 0xFFFF, 119 .src = {
112 .dst.protonum = 0xFF, 120 .u = {
121 .udp = {
122 .port = 0xFFFF,
123 }
124 }
125 },
126 .dst = {
127 .protonum = 0xFF,
128 },
113 }, 129 },
114 .max_expected = 1, 130 .max_expected = 1,
115 .me = THIS_MODULE, 131 .me = THIS_MODULE,
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f115a84a4ac6..f057025a719e 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -92,10 +92,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
92 fl.fl_ip_sport = tcph->dest; 92 fl.fl_ip_sport = tcph->dest;
93 fl.fl_ip_dport = tcph->source; 93 fl.fl_ip_dport = tcph->source;
94 94
95 if (xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0)) { 95 xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
96 dst_release(&rt->u.dst);
97 rt = NULL;
98 }
99 96
100 return rt; 97 return rt;
101} 98}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8c0b14e3beec..8549f26e2495 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1760,6 +1760,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
1760 goto cleanup; 1760 goto cleanup;
1761 } 1761 }
1762 1762
1763 atomic_set(&rth->u.dst.__refcnt, 1);
1763 rth->u.dst.flags= DST_HOST; 1764 rth->u.dst.flags= DST_HOST;
1764#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 1765#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
1765 if (res->fi->fib_nhs > 1) 1766 if (res->fi->fib_nhs > 1)
@@ -1820,7 +1821,6 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
1820 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth); 1821 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
1821 if (err) 1822 if (err)
1822 return err; 1823 return err;
1823 atomic_set(&rth->u.dst.__refcnt, 1);
1824 1824
1825 /* put it into the cache */ 1825 /* put it into the cache */
1826 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1826 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
@@ -1834,8 +1834,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1834 u32 daddr, u32 saddr, u32 tos) 1834 u32 daddr, u32 saddr, u32 tos)
1835{ 1835{
1836#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 1836#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
1837 struct rtable* rth = NULL; 1837 struct rtable* rth = NULL, *rtres;
1838 unsigned char hop, hopcount, lasthop; 1838 unsigned char hop, hopcount;
1839 int err = -EINVAL; 1839 int err = -EINVAL;
1840 unsigned int hash; 1840 unsigned int hash;
1841 1841
@@ -1844,8 +1844,6 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1844 else 1844 else
1845 hopcount = 1; 1845 hopcount = 1;
1846 1846
1847 lasthop = hopcount - 1;
1848
1849 /* distinguish between multipath and singlepath */ 1847 /* distinguish between multipath and singlepath */
1850 if (hopcount < 2) 1848 if (hopcount < 2)
1851 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, 1849 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
@@ -1855,6 +1853,10 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1855 for (hop = 0; hop < hopcount; hop++) { 1853 for (hop = 0; hop < hopcount; hop++) {
1856 res->nh_sel = hop; 1854 res->nh_sel = hop;
1857 1855
1856 /* put reference to previous result */
1857 if (hop)
1858 ip_rt_put(rtres);
1859
1858 /* create a routing cache entry */ 1860 /* create a routing cache entry */
1859 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, 1861 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
1860 &rth); 1862 &rth);
@@ -1863,7 +1865,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1863 1865
1864 /* put it into the cache */ 1866 /* put it into the cache */
1865 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1867 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
1866 err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); 1868 err = rt_intern_hash(hash, rth, &rtres);
1867 if (err) 1869 if (err)
1868 return err; 1870 return err;
1869 1871
@@ -1873,13 +1875,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1873 FIB_RES_NETMASK(*res), 1875 FIB_RES_NETMASK(*res),
1874 res->prefixlen, 1876 res->prefixlen,
1875 &FIB_RES_NH(*res)); 1877 &FIB_RES_NH(*res));
1876
1877 /* only for the last hop the reference count is handled
1878 * outside
1879 */
1880 if (hop == lasthop)
1881 atomic_set(&(skb->dst->__refcnt), 1);
1882 } 1878 }
1879 skb->dst = &rtres->u.dst;
1883 return err; 1880 return err;
1884#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ 1881#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
1885 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos); 1882 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
@@ -2208,6 +2205,7 @@ static inline int __mkroute_output(struct rtable **result,
2208 goto cleanup; 2205 goto cleanup;
2209 } 2206 }
2210 2207
2208 atomic_set(&rth->u.dst.__refcnt, 1);
2211 rth->u.dst.flags= DST_HOST; 2209 rth->u.dst.flags= DST_HOST;
2212#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 2210#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
2213 if (res->fi) { 2211 if (res->fi) {
@@ -2290,8 +2288,6 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
2290 if (err == 0) { 2288 if (err == 0) {
2291 u32 tos = RT_FL_TOS(oldflp); 2289 u32 tos = RT_FL_TOS(oldflp);
2292 2290
2293 atomic_set(&rth->u.dst.__refcnt, 1);
2294
2295 hash = rt_hash_code(oldflp->fl4_dst, 2291 hash = rt_hash_code(oldflp->fl4_dst,
2296 oldflp->fl4_src ^ (oldflp->oif << 5), tos); 2292 oldflp->fl4_src ^ (oldflp->oif << 5), tos);
2297 err = rt_intern_hash(hash, rth, rp); 2293 err = rt_intern_hash(hash, rth, rp);
@@ -2326,6 +2322,10 @@ static inline int ip_mkroute_output(struct rtable** rp,
2326 dev2nexthop = FIB_RES_DEV(*res); 2322 dev2nexthop = FIB_RES_DEV(*res);
2327 dev_hold(dev2nexthop); 2323 dev_hold(dev2nexthop);
2328 2324
2325 /* put reference to previous result */
2326 if (hop)
2327 ip_rt_put(*rp);
2328
2329 err = __mkroute_output(&rth, res, fl, oldflp, 2329 err = __mkroute_output(&rth, res, fl, oldflp,
2330 dev2nexthop, flags); 2330 dev2nexthop, flags);
2331 2331
@@ -2350,7 +2350,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
2350 if (err != 0) 2350 if (err != 0)
2351 return err; 2351 return err;
2352 } 2352 }
2353 atomic_set(&(*rp)->u.dst.__refcnt, 1);
2354 return err; 2353 return err;
2355 } else { 2354 } else {
2356 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, 2355 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out,
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 6094db5e11be..15e1134da1b2 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -499,7 +499,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
499 /* If this packet has been sent out already, we must 499 /* If this packet has been sent out already, we must
500 * adjust the various packet counters. 500 * adjust the various packet counters.
501 */ 501 */
502 if (after(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) { 502 if (!before(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
503 int diff = old_factor - tcp_skb_pcount(skb) - 503 int diff = old_factor - tcp_skb_pcount(skb) -
504 tcp_skb_pcount(buff); 504 tcp_skb_pcount(buff);
505 505
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e5beca7de86c..e0bd1013cb0d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1141,7 +1141,7 @@ int udp_rcv(struct sk_buff *skb)
1141 if (ulen > len || ulen < sizeof(*uh)) 1141 if (ulen > len || ulen < sizeof(*uh))
1142 goto short_packet; 1142 goto short_packet;
1143 1143
1144 if (pskb_trim(skb, ulen)) 1144 if (pskb_trim_rcsum(skb, ulen))
1145 goto short_packet; 1145 goto short_packet;
1146 1146
1147 if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0) 1147 if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 01468fab3d3d..cc518405b3e1 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -175,10 +175,8 @@ ipv4_connected:
175 if (final_p) 175 if (final_p)
176 ipv6_addr_copy(&fl.fl6_dst, final_p); 176 ipv6_addr_copy(&fl.fl6_dst, final_p);
177 177
178 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 178 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
179 dst_release(dst);
180 goto out; 179 goto out;
181 }
182 180
183 /* source address lookup done in ip6_dst_lookup */ 181 /* source address lookup done in ip6_dst_lookup */
184 182
@@ -390,32 +388,101 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
390 put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim); 388 put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
391 } 389 }
392 390
391 if (np->rxopt.bits.rxtclass) {
392 int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff;
393 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
394 }
395
393 if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) { 396 if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
394 u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK; 397 u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
395 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo); 398 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
396 } 399 }
400
401 /* HbH is allowed only once */
397 if (np->rxopt.bits.hopopts && opt->hop) { 402 if (np->rxopt.bits.hopopts && opt->hop) {
398 u8 *ptr = skb->nh.raw + opt->hop; 403 u8 *ptr = skb->nh.raw + opt->hop;
399 put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr); 404 put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
400 } 405 }
401 if (np->rxopt.bits.dstopts && opt->dst0) { 406
407 if (opt->lastopt &&
408 (np->rxopt.bits.dstopts || np->rxopt.bits.srcrt)) {
409 /*
410 * Silly enough, but we need to reparse in order to
411 * report extension headers (except for HbH)
412 * in order.
413 *
414 * Also note that IPV6_RECVRTHDRDSTOPTS is NOT
415 * (and WILL NOT be) defined because
416 * IPV6_RECVDSTOPTS is more generic. --yoshfuji
417 */
418 unsigned int off = sizeof(struct ipv6hdr);
419 u8 nexthdr = skb->nh.ipv6h->nexthdr;
420
421 while (off <= opt->lastopt) {
422 unsigned len;
423 u8 *ptr = skb->nh.raw + off;
424
425 switch(nexthdr) {
426 case IPPROTO_DSTOPTS:
427 nexthdr = ptr[0];
428 len = (ptr[1] + 1) << 3;
429 if (np->rxopt.bits.dstopts)
430 put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
431 break;
432 case IPPROTO_ROUTING:
433 nexthdr = ptr[0];
434 len = (ptr[1] + 1) << 3;
435 if (np->rxopt.bits.srcrt)
436 put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
437 break;
438 case IPPROTO_AH:
439 nexthdr = ptr[0];
440 len = (ptr[1] + 1) << 2;
441 break;
442 default:
443 nexthdr = ptr[0];
444 len = (ptr[1] + 1) << 3;
445 break;
446 }
447
448 off += len;
449 }
450 }
451
452 /* socket options in old style */
453 if (np->rxopt.bits.rxoinfo) {
454 struct in6_pktinfo src_info;
455
456 src_info.ipi6_ifindex = opt->iif;
457 ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
458 put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
459 }
460 if (np->rxopt.bits.rxohlim) {
461 int hlim = skb->nh.ipv6h->hop_limit;
462 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
463 }
464 if (np->rxopt.bits.ohopopts && opt->hop) {
465 u8 *ptr = skb->nh.raw + opt->hop;
466 put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
467 }
468 if (np->rxopt.bits.odstopts && opt->dst0) {
402 u8 *ptr = skb->nh.raw + opt->dst0; 469 u8 *ptr = skb->nh.raw + opt->dst0;
403 put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr); 470 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
404 } 471 }
405 if (np->rxopt.bits.srcrt && opt->srcrt) { 472 if (np->rxopt.bits.osrcrt && opt->srcrt) {
406 struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt); 473 struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
407 put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr); 474 put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
408 } 475 }
409 if (np->rxopt.bits.dstopts && opt->dst1) { 476 if (np->rxopt.bits.odstopts && opt->dst1) {
410 u8 *ptr = skb->nh.raw + opt->dst1; 477 u8 *ptr = skb->nh.raw + opt->dst1;
411 put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr); 478 put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
412 } 479 }
413 return 0; 480 return 0;
414} 481}
415 482
416int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, 483int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
417 struct ipv6_txoptions *opt, 484 struct ipv6_txoptions *opt,
418 int *hlimit) 485 int *hlimit, int *tclass)
419{ 486{
420 struct in6_pktinfo *src_info; 487 struct in6_pktinfo *src_info;
421 struct cmsghdr *cmsg; 488 struct cmsghdr *cmsg;
@@ -438,6 +505,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
438 505
439 switch (cmsg->cmsg_type) { 506 switch (cmsg->cmsg_type) {
440 case IPV6_PKTINFO: 507 case IPV6_PKTINFO:
508 case IPV6_2292PKTINFO:
441 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) { 509 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
442 err = -EINVAL; 510 err = -EINVAL;
443 goto exit_f; 511 goto exit_f;
@@ -492,6 +560,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
492 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg); 560 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);
493 break; 561 break;
494 562
563 case IPV6_2292HOPOPTS:
495 case IPV6_HOPOPTS: 564 case IPV6_HOPOPTS:
496 if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) { 565 if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
497 err = -EINVAL; 566 err = -EINVAL;
@@ -512,7 +581,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
512 opt->hopopt = hdr; 581 opt->hopopt = hdr;
513 break; 582 break;
514 583
515 case IPV6_DSTOPTS: 584 case IPV6_2292DSTOPTS:
516 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) { 585 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
517 err = -EINVAL; 586 err = -EINVAL;
518 goto exit_f; 587 goto exit_f;
@@ -536,6 +605,33 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
536 opt->dst1opt = hdr; 605 opt->dst1opt = hdr;
537 break; 606 break;
538 607
608 case IPV6_DSTOPTS:
609 case IPV6_RTHDRDSTOPTS:
610 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
611 err = -EINVAL;
612 goto exit_f;
613 }
614
615 hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
616 len = ((hdr->hdrlen + 1) << 3);
617 if (cmsg->cmsg_len < CMSG_LEN(len)) {
618 err = -EINVAL;
619 goto exit_f;
620 }
621 if (!capable(CAP_NET_RAW)) {
622 err = -EPERM;
623 goto exit_f;
624 }
625 if (cmsg->cmsg_type == IPV6_DSTOPTS) {
626 opt->opt_flen += len;
627 opt->dst1opt = hdr;
628 } else {
629 opt->opt_nflen += len;
630 opt->dst0opt = hdr;
631 }
632 break;
633
634 case IPV6_2292RTHDR:
539 case IPV6_RTHDR: 635 case IPV6_RTHDR:
540 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) { 636 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
541 err = -EINVAL; 637 err = -EINVAL;
@@ -568,7 +664,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
568 opt->opt_nflen += len; 664 opt->opt_nflen += len;
569 opt->srcrt = rthdr; 665 opt->srcrt = rthdr;
570 666
571 if (opt->dst1opt) { 667 if (cmsg->cmsg_type == IPV6_2292RTHDR && opt->dst1opt) {
572 int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3); 668 int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3);
573 669
574 opt->opt_nflen += dsthdrlen; 670 opt->opt_nflen += dsthdrlen;
@@ -579,6 +675,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
579 675
580 break; 676 break;
581 677
678 case IPV6_2292HOPLIMIT:
582 case IPV6_HOPLIMIT: 679 case IPV6_HOPLIMIT:
583 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) { 680 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
584 err = -EINVAL; 681 err = -EINVAL;
@@ -588,6 +685,24 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
588 *hlimit = *(int *)CMSG_DATA(cmsg); 685 *hlimit = *(int *)CMSG_DATA(cmsg);
589 break; 686 break;
590 687
688 case IPV6_TCLASS:
689 {
690 int tc;
691
692 err = -EINVAL;
693 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
694 goto exit_f;
695 }
696
697 tc = *(int *)CMSG_DATA(cmsg);
698 if (tc < 0 || tc > 0xff)
699 goto exit_f;
700
701 err = 0;
702 *tclass = tc;
703
704 break;
705 }
591 default: 706 default:
592 LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", 707 LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
593 cmsg->cmsg_type); 708 cmsg->cmsg_type);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 5be6da2584ee..47122728212a 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -164,6 +164,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
164 return -1; 164 return -1;
165 } 165 }
166 166
167 opt->lastopt = skb->h.raw - skb->nh.raw;
167 opt->dst1 = skb->h.raw - skb->nh.raw; 168 opt->dst1 = skb->h.raw - skb->nh.raw;
168 169
169 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { 170 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
@@ -243,6 +244,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
243 244
244looped_back: 245looped_back:
245 if (hdr->segments_left == 0) { 246 if (hdr->segments_left == 0) {
247 opt->lastopt = skb->h.raw - skb->nh.raw;
246 opt->srcrt = skb->h.raw - skb->nh.raw; 248 opt->srcrt = skb->h.raw - skb->nh.raw;
247 skb->h.raw += (hdr->hdrlen + 1) << 3; 249 skb->h.raw += (hdr->hdrlen + 1) << 3;
248 opt->dst0 = opt->dst1; 250 opt->dst0 = opt->dst1;
@@ -459,11 +461,10 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
459 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); 461 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
460 goto drop; 462 goto drop;
461 } 463 }
462 if (pkt_len + sizeof(struct ipv6hdr) < skb->len) { 464
463 __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr)); 465 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
464 if (skb->ip_summed == CHECKSUM_HW) 466 goto drop;
465 skb->ip_summed = CHECKSUM_NONE; 467
466 }
467 return 1; 468 return 1;
468 469
469drop: 470drop:
@@ -539,10 +540,15 @@ void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
539 u8 *proto, 540 u8 *proto,
540 struct in6_addr **daddr) 541 struct in6_addr **daddr)
541{ 542{
542 if (opt->srcrt) 543 if (opt->srcrt) {
543 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr); 544 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
544 if (opt->dst0opt) 545 /*
545 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt); 546 * IPV6_RTHDRDSTOPTS is ignored
547 * unless IPV6_RTHDR is set (RFC3542).
548 */
549 if (opt->dst0opt)
550 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
551 }
546 if (opt->hopopt) 552 if (opt->hopopt)
547 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt); 553 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
548} 554}
@@ -573,3 +579,97 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
573 } 579 }
574 return opt2; 580 return opt2;
575} 581}
582
583static int ipv6_renew_option(void *ohdr,
584 struct ipv6_opt_hdr __user *newopt, int newoptlen,
585 int inherit,
586 struct ipv6_opt_hdr **hdr,
587 char **p)
588{
589 if (inherit) {
590 if (ohdr) {
591 memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
592 *hdr = (struct ipv6_opt_hdr *)*p;
593 *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
594 }
595 } else {
596 if (newopt) {
597 if (copy_from_user(*p, newopt, newoptlen))
598 return -EFAULT;
599 *hdr = (struct ipv6_opt_hdr *)*p;
600 if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
601 return -EINVAL;
602 *p += CMSG_ALIGN(newoptlen);
603 }
604 }
605 return 0;
606}
607
608struct ipv6_txoptions *
609ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
610 int newtype,
611 struct ipv6_opt_hdr __user *newopt, int newoptlen)
612{
613 int tot_len = 0;
614 char *p;
615 struct ipv6_txoptions *opt2;
616 int err;
617
618 if (newtype != IPV6_HOPOPTS && opt->hopopt)
619 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
620 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
621 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
622 if (newtype != IPV6_RTHDR && opt->srcrt)
623 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
624 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
625 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
626 if (newopt && newoptlen)
627 tot_len += CMSG_ALIGN(newoptlen);
628
629 if (!tot_len)
630 return NULL;
631
632 opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
633 if (!opt2)
634 return ERR_PTR(-ENOBUFS);
635
636 memset(opt2, 0, tot_len);
637
638 opt2->tot_len = tot_len;
639 p = (char *)(opt2 + 1);
640
641 err = ipv6_renew_option(opt->hopopt, newopt, newoptlen,
642 newtype != IPV6_HOPOPTS,
643 &opt2->hopopt, &p);
644 if (err)
645 goto out;
646
647 err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen,
648 newtype != IPV6_RTHDRDSTOPTS,
649 &opt2->dst0opt, &p);
650 if (err)
651 goto out;
652
653 err = ipv6_renew_option(opt->srcrt, newopt, newoptlen,
654 newtype != IPV6_RTHDR,
655 (struct ipv6_opt_hdr **)opt2->srcrt, &p);
656 if (err)
657 goto out;
658
659 err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen,
660 newtype != IPV6_DSTOPTS,
661 &opt2->dst1opt, &p);
662 if (err)
663 goto out;
664
665 opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
666 (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
667 (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
668 opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
669
670 return opt2;
671out:
672 sock_kfree_s(sk, p, tot_len);
673 return ERR_PTR(err);
674}
675
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index fa8f1bb0aa52..b7185fb3377c 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -287,7 +287,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
287 int iif = 0; 287 int iif = 0;
288 int addr_type = 0; 288 int addr_type = 0;
289 int len; 289 int len;
290 int hlimit; 290 int hlimit, tclass;
291 int err = 0; 291 int err = 0;
292 292
293 if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail) 293 if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -374,7 +374,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
374 if (err) 374 if (err)
375 goto out; 375 goto out;
376 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 376 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
377 goto out_dst_release; 377 goto out;
378 378
379 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 379 if (ipv6_addr_is_multicast(&fl.fl6_dst))
380 hlimit = np->mcast_hops; 380 hlimit = np->mcast_hops;
@@ -385,6 +385,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
385 if (hlimit < 0) 385 if (hlimit < 0)
386 hlimit = ipv6_get_hoplimit(dst->dev); 386 hlimit = ipv6_get_hoplimit(dst->dev);
387 387
388 tclass = np->cork.tclass;
389 if (tclass < 0)
390 tclass = 0;
391
388 msg.skb = skb; 392 msg.skb = skb;
389 msg.offset = skb->nh.raw - skb->data; 393 msg.offset = skb->nh.raw - skb->data;
390 394
@@ -400,7 +404,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
400 err = ip6_append_data(sk, icmpv6_getfrag, &msg, 404 err = ip6_append_data(sk, icmpv6_getfrag, &msg,
401 len + sizeof(struct icmp6hdr), 405 len + sizeof(struct icmp6hdr),
402 sizeof(struct icmp6hdr), 406 sizeof(struct icmp6hdr),
403 hlimit, NULL, &fl, (struct rt6_info*)dst, 407 hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
404 MSG_DONTWAIT); 408 MSG_DONTWAIT);
405 if (err) { 409 if (err) {
406 ip6_flush_pending_frames(sk); 410 ip6_flush_pending_frames(sk);
@@ -434,6 +438,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
434 struct dst_entry *dst; 438 struct dst_entry *dst;
435 int err = 0; 439 int err = 0;
436 int hlimit; 440 int hlimit;
441 int tclass;
437 442
438 saddr = &skb->nh.ipv6h->daddr; 443 saddr = &skb->nh.ipv6h->daddr;
439 444
@@ -464,7 +469,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
464 if (err) 469 if (err)
465 goto out; 470 goto out;
466 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 471 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
467 goto out_dst_release; 472 goto out;
468 473
469 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 474 if (ipv6_addr_is_multicast(&fl.fl6_dst))
470 hlimit = np->mcast_hops; 475 hlimit = np->mcast_hops;
@@ -475,13 +480,17 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
475 if (hlimit < 0) 480 if (hlimit < 0)
476 hlimit = ipv6_get_hoplimit(dst->dev); 481 hlimit = ipv6_get_hoplimit(dst->dev);
477 482
483 tclass = np->cork.tclass;
484 if (tclass < 0)
485 tclass = 0;
486
478 idev = in6_dev_get(skb->dev); 487 idev = in6_dev_get(skb->dev);
479 488
480 msg.skb = skb; 489 msg.skb = skb;
481 msg.offset = 0; 490 msg.offset = 0;
482 491
483 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), 492 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
484 sizeof(struct icmp6hdr), hlimit, NULL, &fl, 493 sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
485 (struct rt6_info*)dst, MSG_DONTWAIT); 494 (struct rt6_info*)dst, MSG_DONTWAIT);
486 495
487 if (err) { 496 if (err) {
@@ -496,7 +505,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
496out_put: 505out_put:
497 if (likely(idev != NULL)) 506 if (likely(idev != NULL))
498 in6_dev_put(idev); 507 in6_dev_put(idev);
499out_dst_release:
500 dst_release(dst); 508 dst_release(dst);
501out: 509out:
502 icmpv6_xmit_unlock(); 510 icmpv6_xmit_unlock();
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index b6c73da5ff35..a7db762de14a 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -225,16 +225,20 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
225 struct ip6_flowlabel * fl, 225 struct ip6_flowlabel * fl,
226 struct ipv6_txoptions * fopt) 226 struct ipv6_txoptions * fopt)
227{ 227{
228 struct ipv6_txoptions * fl_opt = fl->opt; 228 struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
229 229
230 if (fopt == NULL || fopt->opt_flen == 0) 230 if (fopt == NULL || fopt->opt_flen == 0) {
231 return fl_opt; 231 if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
232 return fl_opt;
233 }
232 234
233 if (fl_opt != NULL) { 235 if (fl_opt != NULL) {
234 opt_space->hopopt = fl_opt->hopopt; 236 opt_space->hopopt = fl_opt->hopopt;
235 opt_space->dst0opt = fl_opt->dst0opt; 237 opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
236 opt_space->srcrt = fl_opt->srcrt; 238 opt_space->srcrt = fl_opt->srcrt;
237 opt_space->opt_nflen = fl_opt->opt_nflen; 239 opt_space->opt_nflen = fl_opt->opt_nflen;
240 if (fl_opt->dst0opt && !fl_opt->srcrt)
241 opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
238 } else { 242 } else {
239 if (fopt->opt_nflen == 0) 243 if (fopt->opt_nflen == 0)
240 return fopt; 244 return fopt;
@@ -310,7 +314,7 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int *
310 msg.msg_control = (void*)(fl->opt+1); 314 msg.msg_control = (void*)(fl->opt+1);
311 flowi.oif = 0; 315 flowi.oif = 0;
312 316
313 err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk); 317 err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
314 if (err) 318 if (err)
315 goto done; 319 goto done;
316 err = -EINVAL; 320 err = -EINVAL;
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));
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 09613729404c..cf94372d1af3 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -673,11 +673,12 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
673 673
674 if ((dst = ip6_tnl_dst_check(t)) != NULL) 674 if ((dst = ip6_tnl_dst_check(t)) != NULL)
675 dst_hold(dst); 675 dst_hold(dst);
676 else 676 else {
677 dst = ip6_route_output(NULL, &fl); 677 dst = ip6_route_output(NULL, &fl);
678 678
679 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0) 679 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
680 goto tx_err_link_failure; 680 goto tx_err_link_failure;
681 }
681 682
682 tdev = dst->dev; 683 tdev = dst->dev;
683 684
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 76466af8331e..8567873d0dd8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -210,39 +210,139 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
210 retv = 0; 210 retv = 0;
211 break; 211 break;
212 212
213 case IPV6_PKTINFO: 213 case IPV6_RECVPKTINFO:
214 np->rxopt.bits.rxinfo = valbool; 214 np->rxopt.bits.rxinfo = valbool;
215 retv = 0; 215 retv = 0;
216 break; 216 break;
217
218 case IPV6_2292PKTINFO:
219 np->rxopt.bits.rxoinfo = valbool;
220 retv = 0;
221 break;
217 222
218 case IPV6_HOPLIMIT: 223 case IPV6_RECVHOPLIMIT:
219 np->rxopt.bits.rxhlim = valbool; 224 np->rxopt.bits.rxhlim = valbool;
220 retv = 0; 225 retv = 0;
221 break; 226 break;
222 227
223 case IPV6_RTHDR: 228 case IPV6_2292HOPLIMIT:
229 np->rxopt.bits.rxohlim = valbool;
230 retv = 0;
231 break;
232
233 case IPV6_RECVRTHDR:
224 if (val < 0 || val > 2) 234 if (val < 0 || val > 2)
225 goto e_inval; 235 goto e_inval;
226 np->rxopt.bits.srcrt = val; 236 np->rxopt.bits.srcrt = val;
227 retv = 0; 237 retv = 0;
228 break; 238 break;
229 239
230 case IPV6_HOPOPTS: 240 case IPV6_2292RTHDR:
241 if (val < 0 || val > 2)
242 goto e_inval;
243 np->rxopt.bits.osrcrt = val;
244 retv = 0;
245 break;
246
247 case IPV6_RECVHOPOPTS:
231 np->rxopt.bits.hopopts = valbool; 248 np->rxopt.bits.hopopts = valbool;
232 retv = 0; 249 retv = 0;
233 break; 250 break;
234 251
235 case IPV6_DSTOPTS: 252 case IPV6_2292HOPOPTS:
253 np->rxopt.bits.ohopopts = valbool;
254 retv = 0;
255 break;
256
257 case IPV6_RECVDSTOPTS:
236 np->rxopt.bits.dstopts = valbool; 258 np->rxopt.bits.dstopts = valbool;
237 retv = 0; 259 retv = 0;
238 break; 260 break;
239 261
262 case IPV6_2292DSTOPTS:
263 np->rxopt.bits.odstopts = valbool;
264 retv = 0;
265 break;
266
267 case IPV6_TCLASS:
268 if (val < 0 || val > 0xff)
269 goto e_inval;
270 np->tclass = val;
271 retv = 0;
272 break;
273
274 case IPV6_RECVTCLASS:
275 np->rxopt.bits.rxtclass = valbool;
276 retv = 0;
277 break;
278
240 case IPV6_FLOWINFO: 279 case IPV6_FLOWINFO:
241 np->rxopt.bits.rxflow = valbool; 280 np->rxopt.bits.rxflow = valbool;
242 retv = 0; 281 retv = 0;
243 break; 282 break;
244 283
245 case IPV6_PKTOPTIONS: 284 case IPV6_HOPOPTS:
285 case IPV6_RTHDRDSTOPTS:
286 case IPV6_RTHDR:
287 case IPV6_DSTOPTS:
288 {
289 struct ipv6_txoptions *opt;
290 if (optlen == 0)
291 optval = 0;
292
293 /* hop-by-hop / destination options are privileged option */
294 retv = -EPERM;
295 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
296 break;
297
298 retv = -EINVAL;
299 if (optlen & 0x7 || optlen > 8 * 255)
300 break;
301
302 opt = ipv6_renew_options(sk, np->opt, optname,
303 (struct ipv6_opt_hdr __user *)optval,
304 optlen);
305 if (IS_ERR(opt)) {
306 retv = PTR_ERR(opt);
307 break;
308 }
309
310 /* routing header option needs extra check */
311 if (optname == IPV6_RTHDR && opt->srcrt) {
312 struct ipv6_rt_hdr *rthdr = opt->srcrt;
313 if (rthdr->type)
314 goto sticky_done;
315 if ((rthdr->hdrlen & 1) ||
316 (rthdr->hdrlen >> 1) != rthdr->segments_left)
317 goto sticky_done;
318 }
319
320 retv = 0;
321 if (sk->sk_type == SOCK_STREAM) {
322 if (opt) {
323 struct tcp_sock *tp = tcp_sk(sk);
324 if (!((1 << sk->sk_state) &
325 (TCPF_LISTEN | TCPF_CLOSE))
326 && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
327 tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
328 tcp_sync_mss(sk, tp->pmtu_cookie);
329 }
330 }
331 opt = xchg(&np->opt, opt);
332 sk_dst_reset(sk);
333 } else {
334 write_lock(&sk->sk_dst_lock);
335 opt = xchg(&np->opt, opt);
336 write_unlock(&sk->sk_dst_lock);
337 sk_dst_reset(sk);
338 }
339sticky_done:
340 if (opt)
341 sock_kfree_s(sk, opt, opt->tot_len);
342 break;
343 }
344
345 case IPV6_2292PKTOPTIONS:
246 { 346 {
247 struct ipv6_txoptions *opt = NULL; 347 struct ipv6_txoptions *opt = NULL;
248 struct msghdr msg; 348 struct msghdr msg;
@@ -276,7 +376,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
276 msg.msg_controllen = optlen; 376 msg.msg_controllen = optlen;
277 msg.msg_control = (void*)(opt+1); 377 msg.msg_control = (void*)(opt+1);
278 378
279 retv = datagram_send_ctl(&msg, &fl, opt, &junk); 379 retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
280 if (retv) 380 if (retv)
281 goto done; 381 goto done;
282update: 382update:
@@ -529,6 +629,17 @@ e_inval:
529 return -EINVAL; 629 return -EINVAL;
530} 630}
531 631
632int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
633 char __user *optval, int len)
634{
635 if (!hdr)
636 return 0;
637 len = min_t(int, len, ipv6_optlen(hdr));
638 if (copy_to_user(optval, hdr, ipv6_optlen(hdr)))
639 return -EFAULT;
640 return len;
641}
642
532int ipv6_getsockopt(struct sock *sk, int level, int optname, 643int ipv6_getsockopt(struct sock *sk, int level, int optname,
533 char __user *optval, int __user *optlen) 644 char __user *optval, int __user *optlen)
534{ 645{
@@ -567,7 +678,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
567 return err; 678 return err;
568 } 679 }
569 680
570 case IPV6_PKTOPTIONS: 681 case IPV6_2292PKTOPTIONS:
571 { 682 {
572 struct msghdr msg; 683 struct msghdr msg;
573 struct sk_buff *skb; 684 struct sk_buff *skb;
@@ -601,6 +712,16 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
601 int hlim = np->mcast_hops; 712 int hlim = np->mcast_hops;
602 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim); 713 put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
603 } 714 }
715 if (np->rxopt.bits.rxoinfo) {
716 struct in6_pktinfo src_info;
717 src_info.ipi6_ifindex = np->mcast_oif;
718 ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
719 put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
720 }
721 if (np->rxopt.bits.rxohlim) {
722 int hlim = np->mcast_hops;
723 put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
724 }
604 } 725 }
605 len -= msg.msg_controllen; 726 len -= msg.msg_controllen;
606 return put_user(len, optlen); 727 return put_user(len, optlen);
@@ -625,26 +746,67 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
625 val = np->ipv6only; 746 val = np->ipv6only;
626 break; 747 break;
627 748
628 case IPV6_PKTINFO: 749 case IPV6_RECVPKTINFO:
629 val = np->rxopt.bits.rxinfo; 750 val = np->rxopt.bits.rxinfo;
630 break; 751 break;
631 752
632 case IPV6_HOPLIMIT: 753 case IPV6_2292PKTINFO:
754 val = np->rxopt.bits.rxoinfo;
755 break;
756
757 case IPV6_RECVHOPLIMIT:
633 val = np->rxopt.bits.rxhlim; 758 val = np->rxopt.bits.rxhlim;
634 break; 759 break;
635 760
636 case IPV6_RTHDR: 761 case IPV6_2292HOPLIMIT:
762 val = np->rxopt.bits.rxohlim;
763 break;
764
765 case IPV6_RECVRTHDR:
637 val = np->rxopt.bits.srcrt; 766 val = np->rxopt.bits.srcrt;
638 break; 767 break;
639 768
769 case IPV6_2292RTHDR:
770 val = np->rxopt.bits.osrcrt;
771 break;
772
640 case IPV6_HOPOPTS: 773 case IPV6_HOPOPTS:
774 case IPV6_RTHDRDSTOPTS:
775 case IPV6_RTHDR:
776 case IPV6_DSTOPTS:
777 {
778
779 lock_sock(sk);
780 len = ipv6_getsockopt_sticky(sk, np->opt->hopopt,
781 optval, len);
782 release_sock(sk);
783 return put_user(len, optlen);
784 }
785
786 case IPV6_RECVHOPOPTS:
641 val = np->rxopt.bits.hopopts; 787 val = np->rxopt.bits.hopopts;
642 break; 788 break;
643 789
644 case IPV6_DSTOPTS: 790 case IPV6_2292HOPOPTS:
791 val = np->rxopt.bits.ohopopts;
792 break;
793
794 case IPV6_RECVDSTOPTS:
645 val = np->rxopt.bits.dstopts; 795 val = np->rxopt.bits.dstopts;
646 break; 796 break;
647 797
798 case IPV6_2292DSTOPTS:
799 val = np->rxopt.bits.odstopts;
800 break;
801
802 case IPV6_TCLASS:
803 val = np->tclass;
804 break;
805
806 case IPV6_RECVTCLASS:
807 val = np->rxopt.bits.rxtclass;
808 break;
809
648 case IPV6_FLOWINFO: 810 case IPV6_FLOWINFO:
649 val = np->rxopt.bits.rxflow; 811 val = np->rxopt.bits.rxflow;
650 break; 812 break;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a7eae30f4554..555a31347eda 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -447,10 +447,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
447 return; 447 return;
448 448
449 err = xfrm_lookup(&dst, &fl, NULL, 0); 449 err = xfrm_lookup(&dst, &fl, NULL, 0);
450 if (err < 0) { 450 if (err < 0)
451 dst_release(dst);
452 return; 451 return;
453 }
454 452
455 if (inc_opt) { 453 if (inc_opt) {
456 if (dev->addr_len) 454 if (dev->addr_len)
@@ -539,10 +537,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
539 return; 537 return;
540 538
541 err = xfrm_lookup(&dst, &fl, NULL, 0); 539 err = xfrm_lookup(&dst, &fl, NULL, 0);
542 if (err < 0) { 540 if (err < 0)
543 dst_release(dst);
544 return; 541 return;
545 }
546 542
547 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); 543 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
548 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); 544 send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
@@ -616,10 +612,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
616 return; 612 return;
617 613
618 err = xfrm_lookup(&dst, &fl, NULL, 0); 614 err = xfrm_lookup(&dst, &fl, NULL, 0);
619 if (err < 0) { 615 if (err < 0)
620 dst_release(dst);
621 return; 616 return;
622 }
623 617
624 len = sizeof(struct icmp6hdr); 618 len = sizeof(struct icmp6hdr);
625 if (dev->addr_len) 619 if (dev->addr_len)
@@ -1353,10 +1347,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1353 return; 1347 return;
1354 1348
1355 err = xfrm_lookup(&dst, &fl, NULL, 0); 1349 err = xfrm_lookup(&dst, &fl, NULL, 0);
1356 if (err) { 1350 if (err)
1357 dst_release(dst);
1358 return; 1351 return;
1359 }
1360 1352
1361 rt = (struct rt6_info *) dst; 1353 rt = (struct rt6_info *) dst;
1362 1354
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 14316c3ebde4..b03e87adca93 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -100,11 +100,8 @@ static void send_reset(struct sk_buff *oldskb)
100 dst = ip6_route_output(NULL, &fl); 100 dst = ip6_route_output(NULL, &fl);
101 if (dst == NULL) 101 if (dst == NULL)
102 return; 102 return;
103 if (dst->error || 103 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
104 xfrm_lookup(&dst, &fl, NULL, 0)) {
105 dst_release(dst);
106 return; 104 return;
107 }
108 105
109 hh_len = (dst->dev->hard_header_len + 15)&~15; 106 hh_len = (dst->dev->hard_header_len + 15)&~15;
110 nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr) 107 nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ed3a76b30fd9..5aa3691c578d 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -655,6 +655,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
655 struct flowi fl; 655 struct flowi fl;
656 int addr_len = msg->msg_namelen; 656 int addr_len = msg->msg_namelen;
657 int hlimit = -1; 657 int hlimit = -1;
658 int tclass = -1;
658 u16 proto; 659 u16 proto;
659 int err; 660 int err;
660 661
@@ -740,7 +741,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
740 memset(opt, 0, sizeof(struct ipv6_txoptions)); 741 memset(opt, 0, sizeof(struct ipv6_txoptions));
741 opt->tot_len = sizeof(struct ipv6_txoptions); 742 opt->tot_len = sizeof(struct ipv6_txoptions);
742 743
743 err = datagram_send_ctl(msg, &fl, opt, &hlimit); 744 err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
744 if (err < 0) { 745 if (err < 0) {
745 fl6_sock_release(flowlabel); 746 fl6_sock_release(flowlabel);
746 return err; 747 return err;
@@ -755,8 +756,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
755 } 756 }
756 if (opt == NULL) 757 if (opt == NULL)
757 opt = np->opt; 758 opt = np->opt;
758 if (flowlabel) 759 opt = fl6_merge_options(&opt_space, flowlabel, opt);
759 opt = fl6_merge_options(&opt_space, flowlabel, opt);
760 760
761 fl.proto = proto; 761 fl.proto = proto;
762 rawv6_probe_proto_opt(&fl, msg); 762 rawv6_probe_proto_opt(&fl, msg);
@@ -782,10 +782,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
782 if (final_p) 782 if (final_p)
783 ipv6_addr_copy(&fl.fl6_dst, final_p); 783 ipv6_addr_copy(&fl.fl6_dst, final_p);
784 784
785 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 785 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
786 dst_release(dst);
787 goto out; 786 goto out;
788 }
789 787
790 if (hlimit < 0) { 788 if (hlimit < 0) {
791 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 789 if (ipv6_addr_is_multicast(&fl.fl6_dst))
@@ -798,6 +796,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
798 hlimit = ipv6_get_hoplimit(dst->dev); 796 hlimit = ipv6_get_hoplimit(dst->dev);
799 } 797 }
800 798
799 if (tclass < 0) {
800 tclass = np->cork.tclass;
801 if (tclass < 0)
802 tclass = 0;
803 }
804
801 if (msg->msg_flags&MSG_CONFIRM) 805 if (msg->msg_flags&MSG_CONFIRM)
802 goto do_confirm; 806 goto do_confirm;
803 807
@@ -806,8 +810,9 @@ back_from_confirm:
806 err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags); 810 err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags);
807 } else { 811 } else {
808 lock_sock(sk); 812 lock_sock(sk);
809 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0, 813 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
810 hlimit, opt, &fl, (struct rt6_info*)dst, msg->msg_flags); 814 len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
815 msg->msg_flags);
811 816
812 if (err) 817 if (err)
813 ip6_flush_pending_frames(sk); 818 ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 9d9e04344c77..e4fe9ee484dd 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -479,12 +479,9 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
479 /* Point into the IP datagram 'data' part. */ 479 /* Point into the IP datagram 'data' part. */
480 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) 480 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
481 goto err; 481 goto err;
482 if (end-offset < skb->len) { 482
483 if (pskb_trim(skb, end - offset)) 483 if (pskb_trim_rcsum(skb, end - offset))
484 goto err; 484 goto err;
485 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
486 skb->ip_summed = CHECKSUM_NONE;
487 }
488 485
489 /* Find out which fragments are in front and at the back of us 486 /* Find out which fragments are in front and at the back of us
490 * in the chain of fragments so far. We must know where to put 487 * in the chain of fragments so far. We must know where to put
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 794734f1d230..80643e6b346b 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -632,10 +632,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
632 if (final_p) 632 if (final_p)
633 ipv6_addr_copy(&fl.fl6_dst, final_p); 633 ipv6_addr_copy(&fl.fl6_dst, final_p);
634 634
635 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 635 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
636 dst_release(dst);
637 goto failure; 636 goto failure;
638 }
639 637
640 if (saddr == NULL) { 638 if (saddr == NULL) {
641 saddr = &fl.fl6_src; 639 saddr = &fl.fl6_src;
@@ -849,7 +847,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
849 if (dst == NULL) { 847 if (dst == NULL) {
850 opt = np->opt; 848 opt = np->opt;
851 if (opt == NULL && 849 if (opt == NULL &&
852 np->rxopt.bits.srcrt == 2 && 850 np->rxopt.bits.osrcrt == 2 &&
853 treq->pktopts) { 851 treq->pktopts) {
854 struct sk_buff *pktopts = treq->pktopts; 852 struct sk_buff *pktopts = treq->pktopts;
855 struct inet6_skb_parm *rxopt = IP6CB(pktopts); 853 struct inet6_skb_parm *rxopt = IP6CB(pktopts);
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
888 } 886 }
889 887
890done: 888done:
891 dst_release(dst);
892 if (opt && opt != np->opt) 889 if (opt && opt != np->opt)
893 sock_kfree_s(sk, opt, opt->tot_len); 890 sock_kfree_s(sk, opt, opt->tot_len);
894 return err; 891 return err;
@@ -915,11 +912,10 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
915 struct inet6_skb_parm *opt = IP6CB(skb); 912 struct inet6_skb_parm *opt = IP6CB(skb);
916 913
917 if (np->rxopt.all) { 914 if (np->rxopt.all) {
918 if ((opt->hop && np->rxopt.bits.hopopts) || 915 if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
919 ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) && 916 ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
920 np->rxopt.bits.rxflow) || 917 (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
921 (opt->srcrt && np->rxopt.bits.srcrt) || 918 ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
922 ((opt->dst1 || opt->dst0) && np->rxopt.bits.dstopts))
923 return 1; 919 return 1;
924 } 920 }
925 return 0; 921 return 0;
@@ -1001,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
1001 /* sk = NULL, but it is safe for now. RST socket required. */ 997 /* sk = NULL, but it is safe for now. RST socket required. */
1002 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { 998 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
1003 999
1004 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { 1000 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
1005 dst_release(buff->dst);
1006 return; 1001 return;
1007 }
1008 1002
1009 ip6_xmit(NULL, buff, &fl, NULL, 0); 1003 ip6_xmit(NULL, buff, &fl, NULL, 0);
1010 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1004 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
@@ -1068,10 +1062,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1068 fl.fl_ip_sport = t1->source; 1062 fl.fl_ip_sport = t1->source;
1069 1063
1070 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { 1064 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
1071 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) { 1065 if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
1072 dst_release(buff->dst);
1073 return; 1066 return;
1074 }
1075 ip6_xmit(NULL, buff, &fl, NULL, 0); 1067 ip6_xmit(NULL, buff, &fl, NULL, 0);
1076 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1068 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
1077 return; 1069 return;
@@ -1190,8 +1182,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1190 TCP_ECN_create_request(req, skb->h.th); 1182 TCP_ECN_create_request(req, skb->h.th);
1191 treq->pktopts = NULL; 1183 treq->pktopts = NULL;
1192 if (ipv6_opt_accepted(sk, skb) || 1184 if (ipv6_opt_accepted(sk, skb) ||
1193 np->rxopt.bits.rxinfo || 1185 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
1194 np->rxopt.bits.rxhlim) { 1186 np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
1195 atomic_inc(&skb->users); 1187 atomic_inc(&skb->users);
1196 treq->pktopts = skb; 1188 treq->pktopts = skb;
1197 } 1189 }
@@ -1288,7 +1280,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1288 if (sk_acceptq_is_full(sk)) 1280 if (sk_acceptq_is_full(sk))
1289 goto out_overflow; 1281 goto out_overflow;
1290 1282
1291 if (np->rxopt.bits.srcrt == 2 && 1283 if (np->rxopt.bits.osrcrt == 2 &&
1292 opt == NULL && treq->pktopts) { 1284 opt == NULL && treq->pktopts) {
1293 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts); 1285 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
1294 if (rxopt->srcrt) 1286 if (rxopt->srcrt)
@@ -1544,9 +1536,9 @@ ipv6_pktoptions:
1544 tp = tcp_sk(sk); 1536 tp = tcp_sk(sk);
1545 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt && 1537 if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
1546 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { 1538 !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
1547 if (np->rxopt.bits.rxinfo) 1539 if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
1548 np->mcast_oif = inet6_iif(opt_skb); 1540 np->mcast_oif = inet6_iif(opt_skb);
1549 if (np->rxopt.bits.rxhlim) 1541 if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
1550 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit; 1542 np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
1551 if (ipv6_opt_accepted(sk, opt_skb)) { 1543 if (ipv6_opt_accepted(sk, opt_skb)) {
1552 skb_set_owner_r(opt_skb, sk); 1544 skb_set_owner_r(opt_skb, sk);
@@ -1734,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk)
1734 1726
1735 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 1727 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
1736 sk->sk_err_soft = -err; 1728 sk->sk_err_soft = -err;
1737 dst_release(dst);
1738 return err; 1729 return err;
1739 } 1730 }
1740 1731
@@ -1787,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
1787 1778
1788 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { 1779 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
1789 sk->sk_route_caps = 0; 1780 sk->sk_route_caps = 0;
1790 dst_release(dst);
1791 return err; 1781 return err;
1792 } 1782 }
1793 1783
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 390d750449ce..69b146843a20 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -483,7 +483,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
483 } 483 }
484 484
485 if (ulen < skb->len) { 485 if (ulen < skb->len) {
486 if (__pskb_trim(skb, ulen)) 486 if (pskb_trim_rcsum(skb, ulen))
487 goto discard; 487 goto discard;
488 saddr = &skb->nh.ipv6h->saddr; 488 saddr = &skb->nh.ipv6h->saddr;
489 daddr = &skb->nh.ipv6h->daddr; 489 daddr = &skb->nh.ipv6h->daddr;
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
637 int addr_len = msg->msg_namelen; 637 int addr_len = msg->msg_namelen;
638 int ulen = len; 638 int ulen = len;
639 int hlimit = -1; 639 int hlimit = -1;
640 int tclass = -1;
640 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 641 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
641 int err; 642 int err;
642 643
@@ -758,7 +759,7 @@ do_udp_sendmsg:
758 memset(opt, 0, sizeof(struct ipv6_txoptions)); 759 memset(opt, 0, sizeof(struct ipv6_txoptions));
759 opt->tot_len = sizeof(*opt); 760 opt->tot_len = sizeof(*opt);
760 761
761 err = datagram_send_ctl(msg, fl, opt, &hlimit); 762 err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
762 if (err < 0) { 763 if (err < 0) {
763 fl6_sock_release(flowlabel); 764 fl6_sock_release(flowlabel);
764 return err; 765 return err;
@@ -773,8 +774,7 @@ do_udp_sendmsg:
773 } 774 }
774 if (opt == NULL) 775 if (opt == NULL)
775 opt = np->opt; 776 opt = np->opt;
776 if (flowlabel) 777 opt = fl6_merge_options(&opt_space, flowlabel, opt);
777 opt = fl6_merge_options(&opt_space, flowlabel, opt);
778 778
779 fl->proto = IPPROTO_UDP; 779 fl->proto = IPPROTO_UDP;
780 ipv6_addr_copy(&fl->fl6_dst, daddr); 780 ipv6_addr_copy(&fl->fl6_dst, daddr);
@@ -799,10 +799,8 @@ do_udp_sendmsg:
799 if (final_p) 799 if (final_p)
800 ipv6_addr_copy(&fl->fl6_dst, final_p); 800 ipv6_addr_copy(&fl->fl6_dst, final_p);
801 801
802 if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) { 802 if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
803 dst_release(dst);
804 goto out; 803 goto out;
805 }
806 804
807 if (hlimit < 0) { 805 if (hlimit < 0) {
808 if (ipv6_addr_is_multicast(&fl->fl6_dst)) 806 if (ipv6_addr_is_multicast(&fl->fl6_dst))
@@ -815,6 +813,12 @@ do_udp_sendmsg:
815 hlimit = ipv6_get_hoplimit(dst->dev); 813 hlimit = ipv6_get_hoplimit(dst->dev);
816 } 814 }
817 815
816 if (tclass < 0) {
817 tclass = np->tclass;
818 if (tclass < 0)
819 tclass = 0;
820 }
821
818 if (msg->msg_flags&MSG_CONFIRM) 822 if (msg->msg_flags&MSG_CONFIRM)
819 goto do_confirm; 823 goto do_confirm;
820back_from_confirm: 824back_from_confirm:
@@ -834,9 +838,10 @@ back_from_confirm:
834 838
835do_append_data: 839do_append_data:
836 up->len += ulen; 840 up->len += ulen;
837 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr), 841 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
838 hlimit, opt, fl, (struct rt6_info*)dst, 842 sizeof(struct udphdr), hlimit, tclass, opt, fl,
839 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 843 (struct rt6_info*)dst,
844 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
840 if (err) 845 if (err)
841 udp_v6_flush_pending_frames(sk); 846 udp_v6_flush_pending_frames(sk);
842 else if (!corkreq) 847 else if (!corkreq)
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index 02891ce2db37..36a77944622b 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -337,13 +337,13 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
337 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); 337 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
338 memcpy(callsign, p + 12, l - 10); 338 memcpy(callsign, p + 12, l - 10);
339 callsign[l - 10] = '\0'; 339 callsign[l - 10] = '\0';
340 facilities->source_call = *asc2ax(callsign); 340 asc2ax(&facilities->source_call, callsign);
341 } 341 }
342 if (*p == FAC_CCITT_SRC_NSAP) { 342 if (*p == FAC_CCITT_SRC_NSAP) {
343 memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN); 343 memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
344 memcpy(callsign, p + 12, l - 10); 344 memcpy(callsign, p + 12, l - 10);
345 callsign[l - 10] = '\0'; 345 callsign[l - 10] = '\0';
346 facilities->dest_call = *asc2ax(callsign); 346 asc2ax(&facilities->dest_call, callsign);
347 } 347 }
348 p += l + 2; 348 p += l + 2;
349 n += l + 2; 349 n += l + 2;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 83c8135e1764..fda737d77edc 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -765,8 +765,8 @@ restart:
765 switch (policy->action) { 765 switch (policy->action) {
766 case XFRM_POLICY_BLOCK: 766 case XFRM_POLICY_BLOCK:
767 /* Prohibit the flow */ 767 /* Prohibit the flow */
768 xfrm_pol_put(policy); 768 err = -EPERM;
769 return -EPERM; 769 goto error;
770 770
771 case XFRM_POLICY_ALLOW: 771 case XFRM_POLICY_ALLOW:
772 if (policy->xfrm_nr == 0) { 772 if (policy->xfrm_nr == 0) {
@@ -782,8 +782,8 @@ restart:
782 */ 782 */
783 dst = xfrm_find_bundle(fl, policy, family); 783 dst = xfrm_find_bundle(fl, policy, family);
784 if (IS_ERR(dst)) { 784 if (IS_ERR(dst)) {
785 xfrm_pol_put(policy); 785 err = PTR_ERR(dst);
786 return PTR_ERR(dst); 786 goto error;
787 } 787 }
788 788
789 if (dst) 789 if (dst)