Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 0/9]: TCP: The Road to Super TSO
From: Herbert Xu @ 2005-06-08 22:10 UTC (permalink / raw)
  To: David S. Miller; +Cc: jheffner, netdev
In-Reply-To: <20050608.144906.77057282.davem@davemloft.net>

On Wed, Jun 08, 2005 at 02:49:06PM -0700, David S. Miller wrote:
> 
> Performance went down, with both TSO enabled and disabled, compared to
> not having the patches applied.

What was the receiver running? Was the performance degradation more
pronounced with TSO enabled?
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH 1/1] sysctl configurable icmperror sourceaddress
From: David S. Miller @ 2005-06-08 21:49 UTC (permalink / raw)
  To: buytenh; +Cc: netdev
In-Reply-To: <20050608214540.GF28207@xi.wantstofly.org>

From: Lennert Buytenhek <buytenh@wantstofly.org>
Date: Wed, 8 Jun 2005 23:45:40 +0200

> Can this patch go in, pretty please?
> 
> Here's the patch again for reference:

We have a similar sysctl for ARP handling, why don't
we make use of it?

^ permalink raw reply

* Re: [PATCH 0/9]: TCP: The Road to Super TSO
From: David S. Miller @ 2005-06-08 21:49 UTC (permalink / raw)
  To: jheffner; +Cc: netdev, herbert
In-Reply-To: <200506081740.11292.jheffner@psc.edu>

From: John Heffner <jheffner@psc.edu>
Subject: Re: [PATCH 0/9]: TCP: The Road to Super TSO
Date: Wed, 8 Jun 2005 17:40:10 -0400

> On Tuesday 07 June 2005 12:08 am, David S. Miller wrote:
> > Some folks, notable the S2IO guys, get performance degradation
> > from the Super TSO v2 patch (they get it from the first version
> > as well).  It's a real pain to spot what causes such things
> > in such a huge patch... so I started splitting things up in
> > a very fine grained manner so we can catch regressions more
> > precisely.
> 
> I'm curious about the details of this.  Is there decreased performance 
> relative to current TSO?  Relative to no TSO?  Sending to just one receiver 
> or many, and is it receiver limited?

The receiver is limited in their tests.  No current generation systems
can fill a 10gbit pipe fully, especially at 1500 byte MTU.

Performance went down, with both TSO enabled and disabled, compared to
not having the patches applied.

That's why I'm going through this entire exercise of doing things one
piece at a time.

^ permalink raw reply

* Re: ipw2100: firmware problem
From: James Ketrenos @ 2005-06-08 21:46 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Jeff Garzik, Netdev list, kernel list, James P. Ketrenos
In-Reply-To: <20050608212707.GA2535@elf.ucw.cz>

Pavel Machek wrote:

>>We've been looking into whether the initrd can have the firmware affixed
>>to the end w/ some magic bytes to identify it.  If it works, enhancing
>>the request_firmware to support both hotplug and an initrd approach may
>>be reasonable.
>>    
>>
>
>That seems pretty ugly to me... imagine more than one driver does this
>:-(.
>  
>
Not ideal, but not *that bad* if there is a standard way to stick the
data on the initrd image.  Its annoying to have to do it, but it does
enable the most usage models and allows the network to be brought up as
early as possible--which other components in the system may be relying on.

>Having a parameter to control this seems a bit too complex to me.
>
>How is 
>
>insmod ipw2100 enable=1
>
>different from
>
>insmod ipw2100
>iwconfig eth1 start_scanning_or_whatever
>
>?
>  
>
It defaults to enabled, so you just need to do:

    insmod ipw2100

and it will auto associate with an open network.  For the use case where
users want the device to load but not initialize, they can use

    insmod ipw2100 disable=1

If hotplug and firmware loading worked early in the init sequence, no
one would have issue with the current model; it works as users expect it
to work.  It magically finds and associates to networks, and your
network scripts can then kick off DHCP, all with little to no special
crafting or utility interfacing. 

James

^ permalink raw reply

* Re: [PATCH 1/1] sysctl configurable icmperror sourceaddress
From: Lennert Buytenhek @ 2005-06-08 21:45 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1118136384.10479.15.camel@jeroens.office.netland.nl>

On Tue, Jun 07, 2005 at 11:26:23AM +0200, J. Simonetti wrote:

> This patch alows you to change the source address of icmp error
> messages. It applies cleanly to 2.6.11.11 and retains the default
> behaviour.
> 
> In the old (default) behaviour icmp error messages are sent with the ip
> of the exiting interface.
> The new behaviour (when the sysctl variable is toggled on), it will send
> the message with the ip of the interface that received the packet that
> caused the icmp error. This is the behaviour network administrators will
> expect from a router. It makes debugging complicated network layouts
> much easier. Also, all 'vendor routers' I know of have the later
> behaviour.

Can this patch go in, pretty please?

Here's the patch again for reference:


--- include/linux/sysctl.h.orig	2004-12-24 22:34:58.000000000 +0100
+++ include/linux/sysctl.h	2005-06-07 10:16:39.730585288 +0200
@@ -345,6 +345,7 @@
 	NET_TCP_MODERATE_RCVBUF=106,
 	NET_TCP_TSO_WIN_DIVISOR=107,
	NET_TCP_BIC_BETA=108,
+	NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
 };
 
 enum {
--- net/ipv4/icmp.c.orig	2004-12-24 22:35:28.000000000 +0100
+++ net/ipv4/icmp.c	2005-06-07 10:15:42.645263576 +0200
@@ -207,6 +207,7 @@
 
 int sysctl_icmp_ratelimit = 1 * HZ;
 int sysctl_icmp_ratemask = 0x1818;
+int sysctl_icmp_errors_use_inbound_ifaddr = 0;
 
 /*
  *	ICMP control array. This specifies what to do with each ICMP.
@@ -511,8 +512,12 @@
 	 */
 
 	saddr = iph->daddr;
-	if (!(rt->rt_flags & RTCF_LOCAL))
-		saddr = 0;
+	if (!(rt->rt_flags & RTCF_LOCAL)) {
+		if(sysctl_icmp_errors_use_inbound_ifaddr)
+			saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
+		else
+			saddr = 0;
+	}
 
 	tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |
 					   IPTOS_PREC_INTERNETCONTROL) :
--- net/ipv4/sysctl_net_ipv4.c.orig	2004-12-24 22:35:23.000000000 +0100
+++ net/ipv4/sysctl_net_ipv4.c	2005-06-07 10:19:44.538490216 +0200
@@ -23,6 +23,7 @@
 extern int sysctl_icmp_echo_ignore_all;
 extern int sysctl_icmp_echo_ignore_broadcasts;
 extern int sysctl_icmp_ignore_bogus_error_responses;
+extern int sysctl_icmp_errors_use_inbound_ifaddr;
 
 /* From ip_fragment.c */
 extern int sysctl_ipfrag_low_thresh;
@@ -396,6 +397,14 @@
 		.proc_handler	= &proc_dointvec
 	},
 	{
+		.ctl_name	= NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,
+		.procname	= "icmp_errors_use_inbound_ifaddr",
+		.data		= &sysctl_icmp_errors_use_inbound_ifaddr,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
 		.ctl_name	= NET_IPV4_ROUTE,
 		.procname	= "route",
 		.maxlen		= 0,

^ permalink raw reply

* Re: [PATCH 0/9]: TCP: The Road to Super TSO
From: John Heffner @ 2005-06-08 21:40 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, herbert
In-Reply-To: <20050606.210846.07641049.davem@davemloft.net>

On Tuesday 07 June 2005 12:08 am, David S. Miller wrote:
> Some folks, notable the S2IO guys, get performance degradation
> from the Super TSO v2 patch (they get it from the first version
> as well).  It's a real pain to spot what causes such things
> in such a huge patch... so I started splitting things up in
> a very fine grained manner so we can catch regressions more
> precisely.

I'm curious about the details of this.  Is there decreased performance 
relative to current TSO?  Relative to no TSO?  Sending to just one receiver 
or many, and is it receiver limited?

  -John

^ permalink raw reply

* Re: ipw2100: firmware problem
From: Pavel Machek @ 2005-06-08 21:27 UTC (permalink / raw)
  To: James Ketrenos; +Cc: Jeff Garzik, Netdev list, kernel list, James P. Ketrenos
In-Reply-To: <42A723D3.3060001@linux.intel.com>

Hi!

> >I'm fighting with firmware problem: if ipw2100 is compiled into
> >kernel, it is loaded while kernel boots and firmware loader is not yet
> >available. That leads to uninitialized (=> useless) adapter.
> >  
> >
> We've been looking into whether the initrd can have the firmware affixed
> to the end w/ some magic bytes to identify it.  If it works, enhancing
> the request_firmware to support both hotplug and an initrd approach may
> be reasonable.

That seems pretty ugly to me... imagine more than one driver does this
:-(.

> >What's the prefered way to solve this one? Only load firmware when
> >user does ifconfig eth1 up? [It is wifi, it looks like it would be
> >better to start firmware sooner so that it can associate to the
> >AP...].
> >  
> >
> The debate goes back and forth on whether devices should come up only
> after they are told, or initialize and start looking for a network as
> soon as the module is loaded.
> 
> I lean more toward having the driver just do what it is told, defaulting
> to trying to scan and associate so link is ready as soon as possible. 
> We've added module parameters to change that behavior (disable and
> associate for the ipw2100).

Having a parameter to control this seems a bit too complex to me.

How is 

insmod ipw2100 enable=1

different from

insmod ipw2100
iwconfig eth1 start_scanning_or_whatever

?

								Pavel

^ permalink raw reply

* Re: [PATCH] net: allow controlling NAPI weight with sysfs
From: David S. Miller @ 2005-06-08 21:24 UTC (permalink / raw)
  To: shemminger
  Cc: mitch.a.williams, netdev, john.ronciak, ganesh.venkatesan,
	jesse.brandeburg
In-Reply-To: <20050602111437.1c492138@dxpl.pdx.osdl.net>

From: Stephen Hemminger <shemminger@osdl.org>
Date: Thu, 2 Jun 2005 11:14:37 -0700

> Simple interface to allow changing network device scheduling weight
> with sysfs. Please consider this for 2.6.12, since risk/impact is small.
> 
> Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

Patch applied, thanks Stephen.

^ permalink raw reply

* Re: netdev munching messages again?
From: randy_dunlap @ 2005-06-08 20:30 UTC (permalink / raw)
  To: David S. Miller; +Cc: tgraf, ralf, hadi, netdev
In-Reply-To: <20050608.131044.31642070.davem@davemloft.net>

On Wed, 08 Jun 2005 13:10:44 -0700 (PDT) David S. Miller wrote:

| Ralf, thanks for all of your effort and time maintaining
| oss.sgi.com for our stay as guests via the netdev list.

Thanks from here also.

| I've created netdev@vger.kernel.org, and folks can start
| to join up there.  If someone knows the appropriate
| archive maintainers to contact (marc.theaimsgroup.com
| et al.) please let them know about this transition.  It
| would be much apprecited.

I've done that before and now.
(made the request, not acked by Hank yet)

---
~Randy

^ permalink raw reply

* Re: netdev munching messages again?
From: David S. Miller @ 2005-06-08 20:10 UTC (permalink / raw)
  To: tgraf; +Cc: ralf, hadi, netdev
In-Reply-To: <20050608200048.GP20969@postel.suug.ch>

From: Thomas Graf <tgraf@suug.ch>
Date: Wed, 8 Jun 2005 22:00:48 +0200

> I'm not worried about a refused connections once in a while, I'm
> worried about that exactly those two messages that have been 
> sitting in _my_ queue due to a refused connection to oss.sgi.com
> have been succesfully delivered and the others have not.
> 
> Is there a messages/time limit somwhere? If so what's the limit?
> I tried with 30 seconds delay between each patch but that didn't
> help.

I see the delay due to SGI's firewall when I send postings
out too, and it's very annoying.

The fact that I can send an email faster to Herbert Xu
in Australia (several thousand miles away) than oss.sgi.com
(which is a short drive away) would be an amusing anecdote
if it didn't negatively impact my work.

I think it's time to move this list to a more reliable and
efficient place.

Ralf, thanks for all of your effort and time maintaining
oss.sgi.com for our stay as guests via the netdev list.

I've created netdev@vger.kernel.org, and folks can start
to join up there.  If someone knows the appropriate
archive maintainers to contact (marc.theaimsgroup.com
et al.) please let them know about this transition.  It
would be much apprecited.

^ permalink raw reply

* Re: netdev munching messages again?
From: Thomas Graf @ 2005-06-08 20:00 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: jamal, David S. Miller, netdev
In-Reply-To: <20050608172809.GF5520@linux-mips.org>

* Ralf Baechle <20050608172809.GF5520@linux-mips.org> 2005-06-08 18:28
> Whatever it was, it was probably a separate issue from this spamfilter
> faux-pas.  Note there is a firewall in front of oss.sgi.com which will
> accept the SMTP TCP connection only to drop the connection shortly after
> if it can't build a connection to the "real" oss.

I'm not worried about a refused connections once in a while, I'm
worried about that exactly those two messages that have been 
sitting in _my_ queue due to a refused connection to oss.sgi.com
have been succesfully delivered and the others have not.

Is there a messages/time limit somwhere? If so what's the limit?
I tried with 30 seconds delay between each patch but that didn't
help.

^ permalink raw reply

* Re: ipw2100: firmware problem
From: David S. Miller @ 2005-06-08 19:54 UTC (permalink / raw)
  To: davej; +Cc: jketreno, vda, pavel, jgarzik, netdev, linux-kernel,
	ipw2100-admin
In-Reply-To: <20050608194902.GK876@redhat.com>

From: Dave Jones <davej@redhat.com>
Date: Wed, 8 Jun 2005 15:49:02 -0400

> FWIW, I agree, though the licensing of the Intel firmware
> prevents that iirc.  The biggest problem I face with this driver
> in Fedora kernels is users mismatching firmware rev with the
> driver version. Another problem that disappears if the two
> are shipped together.

Yep, this license definitely hurts users, in many many ways.

If this kind of external firmware requirement existed for a popular
SCSI controller, more people would be up in arms about this and
understand the issue more clearly.

^ permalink raw reply

* Re: ipw2100: firmware problem
From: Dave Jones @ 2005-06-08 19:49 UTC (permalink / raw)
  To: David S. Miller
  Cc: jketreno, vda, pavel, jgarzik, netdev, linux-kernel,
	ipw2100-admin
In-Reply-To: <20050608.124332.85408883.davem@davemloft.net>

On Wed, Jun 08, 2005 at 12:43:32PM -0700, David S. Miller wrote:
 
 > I am likely to always take the position that device firmware
 > belongs in the kernel proper, not via these userland and filesystem
 > loading mechanism, none of which may be even _available_ when
 > we first need to get the device going.

FWIW, I agree, though the licensing of the Intel firmware
prevents that iirc.  The biggest problem I face with this driver
in Fedora kernels is users mismatching firmware rev with the
driver version. Another problem that disappears if the two
are shipped together.

Of course this would then bring out the armchair lawyers on
the list and cause another 500 emails debating whether it
violates the gpl.

		Dave

^ permalink raw reply

* Re: oops with hostap and 2.6.12-rc6-mm1: Kernel BUG at "net/ipv4/tcp_output.c":928
From: David S. Miller @ 2005-06-08 19:47 UTC (permalink / raw)
  To: belyshev; +Cc: netdev
In-Reply-To: <56hdg93rxb.fsf@depni.sinp.msu.ru>


Just remove the BUG_ON() assertion in tcp_tso_should_defer(),
it's simply not a correct check when FIN is set in the packet.

^ permalink raw reply

* Re: ipw2100: firmware problem
From: David S. Miller @ 2005-06-08 19:43 UTC (permalink / raw)
  To: jketreno; +Cc: vda, pavel, jgarzik, netdev, linux-kernel, ipw2100-admin
In-Reply-To: <42A7268D.9020402@linux.intel.com>

From: James Ketrenos <jketreno@linux.intel.com>
Date: Wed, 08 Jun 2005 12:10:37 -0500

> My approach is to make the driver so it supports as many usage models as
> possible, leaving policy to other components of the system.

I don't see how this kind of firmware load setup handles something
like an NFS root over such a device that requires firmware.

And let's not mention that I have to setup an initrd to make that
work, that's rediculious.

This is the kind of crap that happens when drivers in the kernel
are not self contained, and need "external stuff" to work properly.
It means that simple things like NFS root over the device do not
work in a straightforward, simple, and elegant manner.

I am likely to always take the position that device firmware
belongs in the kernel proper, not via these userland and filesystem
loading mechanism, none of which may be even _available_ when
we first need to get the device going.

^ permalink raw reply

* [patch 2.6.12-rc6] b44: check link state during open
From: John W. Linville @ 2005-06-08 19:11 UTC (permalink / raw)
  To: linux-kernel, netdev; +Cc: jgarzik

Check the link state during b44_open.  This closes a 1 HZ window
that existed after b44_open ran but before the b44_timer handler ran,
during which ethtool would report "Link detected: yes" no matter what
the link state actually was.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---

 drivers/net/b44.c |    3 +++
 1 files changed, 3 insertions(+)

--- linux-2.6.12-rc6/drivers/net/b44.c.orig	2005-06-08 14:52:35.000000000 -0400
+++ linux-2.6.12-rc6/drivers/net/b44.c	2005-06-08 14:52:43.000000000 -0400
@@ -1285,6 +1285,9 @@ static int b44_open(struct net_device *d
 	b44_init_hw(bp);
 	bp->flags |= B44_FLAG_INIT_COMPLETE;
 
+	netif_carrier_off(dev);
+	b44_check_phy(bp);
+
 	spin_unlock_irq(&bp->lock);
 
 	init_timer(&bp->timer);
-- 
John W. Linville
linville@tuxdriver.com

^ permalink raw reply

* Re: IPV6 RFC3542 compliance [PATCH]
From: David Stevens @ 2005-06-08 18:49 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明; +Cc: davem, netdev
In-Reply-To: <20050607.171423.106079530.yoshfuji@linux-ipv6.org>

[-- Attachment #1: Type: text/plain, Size: 23682 bytes --]

Below is a patch that adds a warning message for rfc2292-style
use of socket options, and uses a different numeric value for
options that have a different meaning in the rfc3542 API.
It also, of course, adds support for sending and receiving
traffic class, and the new IPV6_RECVx socket options from
rfc3542.

                                        +-DLS

Signed-off-by: David L Stevens <dlstevens@us.ibm.com>
diff -ruNp linux-2.6.11.10/include/linux/in6.h 
linux-2.6.11.10T3/include/linux/in6.h
--- linux-2.6.11.10/include/linux/in6.h 2005-05-16 10:51:43.000000000 
-0700
+++ linux-2.6.11.10T3/include/linux/in6.h       2005-06-08 
10:45:25.000000000 -0700
@@ -148,10 +148,10 @@ struct in6_flowlabel_req
  */
 
 #define IPV6_ADDRFORM          1
-#define IPV6_PKTINFO           2
-#define IPV6_HOPOPTS           3
-#define IPV6_DSTOPTS           4
-#define IPV6_RTHDR             5
+#define IPV6_2292PKTINFO       2
+#define IPV6_2292HOPOPTS       3
+#define IPV6_2292DSTOPTS       4
+#define IPV6_2292RTHDR         5
 #define IPV6_PKTOPTIONS                6
 #define IPV6_CHECKSUM          7
 #define IPV6_HOPLIMIT          8
@@ -184,6 +184,12 @@ struct in6_flowlabel_req
 
 #define IPV6_IPSEC_POLICY      34
 #define IPV6_XFRM_POLICY       35
+#define IPV6_RECVPKTINFO       36
+#define IPV6_RECVHOPLIMIT      37
+#define IPV6_RECVRTHDR         38
+#define IPV6_RECVHOPOPTS       39
+#define IPV6_RECVDSTOPTS       40
+#define IPV6_RECVTCLASS                41
 
 /*
  * Multicast:
@@ -198,4 +204,11 @@ struct in6_flowlabel_req
  * MCAST_MSFILTER              48
  */
 
+#define IPV6_PKTINFO           49
+#define IPV6_RTHDR             50
+#define IPV6_HOPOPTS           51
+#define IPV6_DSTOPTS           52
+#define IPV6_TCLASS            53
+#define IPV6_RTHDRDSTOPTS      54
+
 #endif
diff -ruNp linux-2.6.11.10/include/linux/ipv6.h 
linux-2.6.11.10T3/include/linux/ipv6.h
--- linux-2.6.11.10/include/linux/ipv6.h        2005-05-16 
10:51:43.000000000 -0700
+++ linux-2.6.11.10T3/include/linux/ipv6.h      2005-06-07 
15:10:28.000000000 -0700
@@ -221,7 +221,8 @@ struct ipv6_pinfo {
                                rxhlim:1,
                                hopopts:1,
                                dstopts:1,
-                                rxflow:1;
+                                rxflow:1,
+                               rxtclass:1;
                } bits;
                __u8            all;
        } rxopt;
@@ -231,7 +232,8 @@ struct ipv6_pinfo {
                                recverr:1,
                                sndflow:1,
                                pmtudisc:2,
-                               ipv6only:1;
+                               ipv6only:1,
+                               rfc2292:1;
 
        struct ipv6_mc_socklist *ipv6_mc_list;
        struct ipv6_ac_socklist *ipv6_ac_list;
@@ -244,6 +246,7 @@ struct ipv6_pinfo {
                struct ipv6_txoptions *opt;
                struct rt6_info *rt;
                int hop_limit;
+               int tclass;
        } cork;
 };
 
diff -ruNp linux-2.6.11.10/include/net/ipv6.h 
linux-2.6.11.10T3/include/net/ipv6.h
--- linux-2.6.11.10/include/net/ipv6.h  2005-05-16 10:51:49.000000000 
-0700
+++ linux-2.6.11.10T3/include/net/ipv6.h        2005-05-24 
14:57:23.000000000 -0700
@@ -347,6 +347,7 @@ extern int                  ip6_append_data(struct 
sock
                                                int length,
                                                int transhdrlen,
                                                int hlimit,
+                                               int tclass,
                                                struct ipv6_txoptions 
*opt,
                                                struct flowi *fl,
                                                struct rt6_info *rt,
diff -ruNp linux-2.6.11.10/include/net/transp_v6.h 
linux-2.6.11.10T3/include/net/transp_v6.h
--- linux-2.6.11.10/include/net/transp_v6.h     2005-05-16 
10:51:51.000000000 -0700
+++ linux-2.6.11.10T3/include/net/transp_v6.h   2005-05-24 
14:04:11.000000000 -0700
@@ -37,7 +37,7 @@ extern int                    datagram_recv_ctl(struct 
so
 extern int                     datagram_send_ctl(struct msghdr *msg,
                                                  struct flowi *fl,
                                                  struct ipv6_txoptions 
*opt,
-                                                 int *hlimit);
+                                                 int *hlimit, int 
*tclass);
 
 #define                LOOPBACK4_IPV6 __constant_htonl(0x7f000006)
 
diff -ruNp linux-2.6.11.10/net/ipv6/datagram.c 
linux-2.6.11.10T3/net/ipv6/datagram.c
--- linux-2.6.11.10/net/ipv6/datagram.c 2005-05-16 10:52:00.000000000 
-0700
+++ linux-2.6.11.10T3/net/ipv6/datagram.c       2005-06-08 
11:29:31.000000000 -0700
@@ -381,13 +381,19 @@ int datagram_recv_ctl(struct sock *sk, s
 
                src_info.ipi6_ifindex = opt->iif;
                ipv6_addr_copy(&src_info.ipi6_addr, 
&skb->nh.ipv6h->daddr);
-               put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), 
&src_info);
+               put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292PKTINFO :
+                       IPV6_PKTINFO, sizeof(src_info), &src_info);
        }
 
        if (np->rxopt.bits.rxhlim) {
                int hlim = skb->nh.ipv6h->hop_limit;
                put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), 
&hlim);
        }
+       if (np->rxopt.bits.rxtclass) {
+               u8 tclass = (skb->nh.ipv6h->priority << 4) |
+                       ((skb->nh.ipv6h->flow_lbl[0]>>4) & 0xf);
+               put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), 
&tclass);
+       }
 
        if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & 
IPV6_FLOWINFO_MASK)) {
                u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
@@ -395,26 +401,30 @@ int datagram_recv_ctl(struct sock *sk, s
        }
        if (np->rxopt.bits.hopopts && opt->hop) {
                u8 *ptr = skb->nh.raw + opt->hop;
-               put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
+               put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292HOPOPTS :
+                       IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
        }
        if (np->rxopt.bits.dstopts && opt->dst0) {
                u8 *ptr = skb->nh.raw + opt->dst0;
-               put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+               put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292DSTOPTS :
+                       IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
        }
        if (np->rxopt.bits.srcrt && opt->srcrt) {
                struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr 
*)(skb->nh.raw + opt->srcrt);
-               put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 
3, rthdr);
+               put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292RTHDR :
+                       IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
        }
        if (np->rxopt.bits.dstopts && opt->dst1) {
                u8 *ptr = skb->nh.raw + opt->dst1;
-               put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+               put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292DSTOPTS :
+                       IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
        }
        return 0;
 }
 
 int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                      struct ipv6_txoptions *opt,
-                     int *hlimit)
+                     int *hlimit, int *tclass)
 {
        struct in6_pktinfo *src_info;
        struct cmsghdr *cmsg;
@@ -436,6 +446,7 @@ int datagram_send_ctl(struct msghdr *msg
                        continue;
 
                switch (cmsg->cmsg_type) {
+               case IPV6_2292PKTINFO:
                case IPV6_PKTINFO:
                        if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct 
in6_pktinfo))) {
                                err = -EINVAL;
@@ -491,6 +502,7 @@ int datagram_send_ctl(struct msghdr *msg
                        fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 
*)CMSG_DATA(cmsg);
                        break;
 
+               case IPV6_2292HOPOPTS:
                case IPV6_HOPOPTS:
                         if (opt->hopopt || cmsg->cmsg_len < 
CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
                                err = -EINVAL;
@@ -511,6 +523,7 @@ int datagram_send_ctl(struct msghdr *msg
                        opt->hopopt = hdr;
                        break;
 
+               case IPV6_2292DSTOPTS:
                case IPV6_DSTOPTS:
                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct 
ipv6_opt_hdr))) {
                                err = -EINVAL;
@@ -535,6 +548,7 @@ int datagram_send_ctl(struct msghdr *msg
                        opt->dst1opt = hdr;
                        break;
 
+               case IPV6_2292RTHDR:
                case IPV6_RTHDR:
                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct 
ipv6_rt_hdr))) {
                                err = -EINVAL;
@@ -587,6 +601,15 @@ int datagram_send_ctl(struct msghdr *msg
                        *hlimit = *(int *)CMSG_DATA(cmsg);
                        break;
 
+               case IPV6_TCLASS:
+                       if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+                               err = -EINVAL;
+                               goto exit_f;
+                       }
+
+                       *tclass = *(int *)CMSG_DATA(cmsg);
+                       break;
+
                default:
                        LIMIT_NETDEBUG(
                                printk(KERN_DEBUG "invalid cmsg type: 
%d\n", cmsg->cmsg_type));
diff -ruNp linux-2.6.11.10/net/ipv6/icmp.c 
linux-2.6.11.10T3/net/ipv6/icmp.c
--- linux-2.6.11.10/net/ipv6/icmp.c     2005-05-16 10:52:00.000000000 
-0700
+++ linux-2.6.11.10T3/net/ipv6/icmp.c   2005-05-24 15:05:14.000000000 
-0700
@@ -287,7 +287,7 @@ void icmpv6_send(struct sk_buff *skb, in
        int iif = 0;
        int addr_type = 0;
        int len;
-       int hlimit;
+       int hlimit, tclass;
        int err = 0;
 
        if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -381,6 +381,9 @@ void icmpv6_send(struct sk_buff *skb, in
                hlimit = np->hop_limit;
        if (hlimit < 0)
                hlimit = dst_metric(dst, RTAX_HOPLIMIT);
+       tclass = np->cork.tclass;
+       if (tclass < 0)
+               tclass = 0;
 
        msg.skb = skb;
        msg.offset = skb->nh.raw - skb->data;
@@ -398,7 +401,7 @@ void icmpv6_send(struct sk_buff *skb, in
        err = ip6_append_data(sk, icmpv6_getfrag, &msg,
                              len + sizeof(struct icmp6hdr),
                              sizeof(struct icmp6hdr),
-                             hlimit, NULL, &fl, (struct rt6_info*)dst,
+                             hlimit, tclass, NULL, &fl, (struct 
rt6_info*)dst,
                              MSG_DONTWAIT);
        if (err) {
                ip6_flush_pending_frames(sk);
@@ -432,6 +435,7 @@ static void icmpv6_echo_reply(struct sk_
        struct dst_entry *dst;
        int err = 0;
        int hlimit;
+       int tclass;
 
        saddr = &skb->nh.ipv6h->daddr;
 
@@ -467,15 +471,18 @@ static void icmpv6_echo_reply(struct sk_
                hlimit = np->hop_limit;
        if (hlimit < 0)
                hlimit = dst_metric(dst, RTAX_HOPLIMIT);
+       tclass = np->cork.tclass;
+       if (tclass < 0)
+               tclass = 0;
 
        idev = in6_dev_get(skb->dev);
 
        msg.skb = skb;
        msg.offset = 0;
 
-       err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + 
sizeof(struct icmp6hdr),
-                               sizeof(struct icmp6hdr), hlimit, NULL, 
&fl,
-                               (struct rt6_info*)dst, MSG_DONTWAIT);
+       err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len +
+               sizeof(struct icmp6hdr), sizeof(struct icmp6hdr), hlimit,
+               tclass, NULL, &fl, (struct rt6_info*)dst, MSG_DONTWAIT);
 
        if (err) {
                ip6_flush_pending_frames(sk);
diff -ruNp linux-2.6.11.10/net/ipv6/ip6_flowlabel.c 
linux-2.6.11.10T3/net/ipv6/ip6_flowlabel.c
--- linux-2.6.11.10/net/ipv6/ip6_flowlabel.c    2005-05-16 
10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/ip6_flowlabel.c  2005-05-24 
14:04:28.000000000 -0700
@@ -311,7 +311,7 @@ fl_create(struct in6_flowlabel_req *freq
                msg.msg_control = (void*)(fl->opt+1);
                flowi.oif = 0;
 
-               err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk);
+               err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, 
&junk);
                if (err)
                        goto done;
                err = -EINVAL;
diff -ruNp linux-2.6.11.10/net/ipv6/ip6_output.c 
linux-2.6.11.10T3/net/ipv6/ip6_output.c
--- linux-2.6.11.10/net/ipv6/ip6_output.c       2005-05-16 
10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/ip6_output.c     2005-05-24 
14:58:51.000000000 -0700
@@ -211,7 +211,7 @@ int ip6_xmit(struct sock *sk, struct sk_
        struct ipv6hdr *hdr;
        u8  proto = fl->proto;
        int seg_len = skb->len;
-       int hlimit;
+       int hlimit, tclass;
        u32 mtu;
 
        if (opt) {
@@ -253,6 +253,13 @@ int ip6_xmit(struct sock *sk, struct sk_
                hlimit = np->hop_limit;
        if (hlimit < 0)
                hlimit = dst_metric(dst, RTAX_HOPLIMIT);
+       tclass = -1;
+       if (np)
+               tclass = np->cork.tclass;
+       if (tclass < 0)
+               tclass = 0;
+       hdr->priority = (np->cork.tclass>>4) &0xf;
+       hdr->flow_lbl[0] |= (np->cork.tclass & 0xf)<<4;
 
        hdr->payload_len = htons(seg_len);
        hdr->nexthdr = proto;
@@ -806,10 +813,11 @@ out_err_release:
        return err;
 }
 
-int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, 
int offset, int len, int odd, struct sk_buff *skb),
-                   void *from, int length, int transhdrlen,
-                   int hlimit, struct ipv6_txoptions *opt, struct flowi 
*fl, struct rt6_info *rt,
-                   unsigned int flags)
+int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+       int offset, int len, int odd, struct sk_buff *skb),
+       void *from, int length, int transhdrlen,
+       int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi 
*fl,
+       struct rt6_info *rt, unsigned int flags)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
@@ -847,6 +855,7 @@ int ip6_append_data(struct sock *sk, int
                np->cork.rt = rt;
                inet->cork.fl = *fl;
                np->cork.hop_limit = hlimit;
+               np->cork.tclass = tclass;
                inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst);
                inet->cork.length = 0;
                sk->sk_sndmsg_page = NULL;
@@ -1130,6 +1139,10 @@ int ip6_push_pending_frames(struct sock 
 
        *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
 
+       /* traffic class */
+       hdr->priority = (np->cork.tclass>>4) & 0xf;
+       hdr->flow_lbl[0] |= (np->cork.tclass & 0xf)<<4;
+
        if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
                hdr->payload_len = htons(skb->len - sizeof(struct 
ipv6hdr));
        else
diff -ruNp linux-2.6.11.10/net/ipv6/ipv6_sockglue.c 
linux-2.6.11.10T3/net/ipv6/ipv6_sockglue.c
--- linux-2.6.11.10/net/ipv6/ipv6_sockglue.c    2005-05-16 
10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/ipv6_sockglue.c  2005-06-08 
11:06:47.000000000 -0700
@@ -115,6 +115,15 @@ extern int ip6_mc_msfilter(struct sock *
 extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
        struct group_filter __user *optval, int __user *optlen);
 
+/*
+ * warn of obsolete RFC 2292 socket API use
+ */
+static void warn2292(char *optname)
+{
+       printk(KERN_WARNING "process '%s' is using obsolete %s socket 
option\n",
+               current->comm, optname);
+}
+
 
 int ipv6_setsockopt(struct sock *sk, int level, int optname,
                    char __user *optval, int optlen)
@@ -208,33 +217,53 @@ int ipv6_setsockopt(struct sock *sk, int
                retv = 0;
                break;
 
-       case IPV6_PKTINFO:
+       case IPV6_2292PKTINFO:
+               warn2292("IPV6_PKTINFO");
+       case IPV6_RECVPKTINFO:
+               np->rfc2292 = optname == IPV6_2292PKTINFO;
                np->rxopt.bits.rxinfo = valbool;
                retv = 0;
                break;
 
        case IPV6_HOPLIMIT:
+               warn2292("IPV6_HOPLIMIT");
+       case IPV6_RECVHOPLIMIT:
+               np->rfc2292 = optname == IPV6_HOPLIMIT;
                np->rxopt.bits.rxhlim = valbool;
                retv = 0;
                break;
 
-       case IPV6_RTHDR:
+       case IPV6_2292RTHDR:
+               warn2292("IPV6_RTHDR");
+       case IPV6_RECVRTHDR:
                if (val < 0 || val > 2)
                        goto e_inval;
+               np->rfc2292 = optname == IPV6_2292RTHDR;
                np->rxopt.bits.srcrt = val;
                retv = 0;
                break;
 
-       case IPV6_HOPOPTS:
+       case IPV6_2292HOPOPTS:
+               warn2292("IPV6_HOPOPTS");
+       case IPV6_RECVHOPOPTS:
+               np->rfc2292 = optname == IPV6_2292HOPOPTS;
                np->rxopt.bits.hopopts = valbool;
                retv = 0;
                break;
 
-       case IPV6_DSTOPTS:
+       case IPV6_2292DSTOPTS:
+               warn2292("IPV6_DSTOPTS");
+       case IPV6_RECVDSTOPTS:
+               np->rfc2292 = optname == IPV6_2292DSTOPTS;
                np->rxopt.bits.dstopts = valbool;
                retv = 0;
                break;
 
+       case IPV6_RECVTCLASS:
+               np->rxopt.bits.rxtclass = valbool;
+               retv = 0;
+               break;
+
        case IPV6_FLOWINFO:
                np->rxopt.bits.rxflow = valbool;
                retv = 0;
@@ -274,7 +303,7 @@ int ipv6_setsockopt(struct sock *sk, int
                msg.msg_controllen = optlen;
                msg.msg_control = (void*)(opt+1);
 
-               retv = datagram_send_ctl(&msg, &fl, opt, &junk);
+               retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
                if (retv)
                        goto done;
 update:
@@ -620,26 +649,45 @@ int ipv6_getsockopt(struct sock *sk, int
                val = np->ipv6only;
                break;
 
-       case IPV6_PKTINFO:
+       case IPV6_2292PKTINFO:
+               warn2292("IPV6_PKTINFO");
+       case IPV6_RECVPKTINFO:
+               np->rfc2292 = optname == IPV6_2292PKTINFO;
                val = np->rxopt.bits.rxinfo;
                break;
 
        case IPV6_HOPLIMIT:
+               warn2292("IPV6_HOPLIMIT");
+       case IPV6_RECVHOPLIMIT:
+               np->rfc2292 = optname == IPV6_HOPLIMIT;
                val = np->rxopt.bits.rxhlim;
                break;
 
-       case IPV6_RTHDR:
+       case IPV6_2292RTHDR:
+               warn2292("IPV6_RTHDR");
+       case IPV6_RECVRTHDR:
+               np->rfc2292 = optname == IPV6_2292RTHDR;
                val = np->rxopt.bits.srcrt;
                break;
 
-       case IPV6_HOPOPTS:
+       case IPV6_2292HOPOPTS:
+               warn2292("IPV6_HOPOPTS");
+       case IPV6_RECVHOPOPTS:
+               np->rfc2292 = optname == IPV6_2292HOPOPTS;
                val = np->rxopt.bits.hopopts;
                break;
 
-       case IPV6_DSTOPTS:
+       case IPV6_2292DSTOPTS:
+               warn2292("IPV6_DSTOPTS");
+       case IPV6_RECVDSTOPTS:
+               np->rfc2292 = optname == IPV6_2292DSTOPTS;
                val = np->rxopt.bits.dstopts;
                break;
 
+       case IPV6_RECVTCLASS:
+               val = np->rxopt.bits.rxtclass;
+               break;
+
        case IPV6_FLOWINFO:
                val = np->rxopt.bits.rxflow;
                break;
diff -ruNp linux-2.6.11.10/net/ipv6/raw.c linux-2.6.11.10T3/net/ipv6/raw.c
--- linux-2.6.11.10/net/ipv6/raw.c      2005-05-16 10:52:00.000000000 
-0700
+++ linux-2.6.11.10T3/net/ipv6/raw.c    2005-05-24 15:09:42.000000000 
-0700
@@ -617,6 +617,7 @@ static int rawv6_sendmsg(struct kiocb *i
        struct flowi fl;
        int addr_len = msg->msg_namelen;
        int hlimit = -1;
+       int tclass = -1;
        u16 proto;
        int err;
 
@@ -702,7 +703,7 @@ static int rawv6_sendmsg(struct kiocb *i
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(struct ipv6_txoptions);
 
-               err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+               err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
@@ -758,6 +759,12 @@ static int rawv6_sendmsg(struct kiocb *i
                        hlimit = dst_metric(dst, RTAX_HOPLIMIT);
        }
 
+       if (tclass < 0) {
+               tclass = np->cork.tclass;
+               if (tclass < 0)
+                       tclass = 0;
+       }
+
        if (msg->msg_flags&MSG_CONFIRM)
                goto do_confirm;
 
@@ -766,8 +773,9 @@ back_from_confirm:
                err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, 
(struct rt6_info*)dst, msg->msg_flags);
        } else {
                lock_sock(sk);
-               err = ip6_append_data(sk, ip_generic_getfrag, 
msg->msg_iov, len, 0,
-                                       hlimit, opt, &fl, (struct 
rt6_info*)dst, msg->msg_flags);
+               err = ip6_append_data(sk, ip_generic_getfrag, 
msg->msg_iov,
+                       len, 0, hlimit, tclass, opt, &fl, (struct 
rt6_info*)dst,
+                       msg->msg_flags);
 
                if (err)
                        ip6_flush_pending_frames(sk);
diff -ruNp linux-2.6.11.10/net/ipv6/udp.c linux-2.6.11.10T3/net/ipv6/udp.c
--- linux-2.6.11.10/net/ipv6/udp.c      2005-05-16 10:52:00.000000000 
-0700
+++ linux-2.6.11.10T3/net/ipv6/udp.c    2005-05-24 15:11:58.000000000 
-0700
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *i
        int addr_len = msg->msg_namelen;
        int ulen = len;
        int hlimit = -1;
+       int tclass = -1;
        int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
        int err;
 
@@ -758,7 +759,7 @@ do_udp_sendmsg:
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(*opt);
 
-               err = datagram_send_ctl(msg, fl, opt, &hlimit);
+               err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
@@ -812,6 +813,11 @@ do_udp_sendmsg:
                if (hlimit < 0)
                        hlimit = dst_metric(dst, RTAX_HOPLIMIT);
        }
+       if (tclass < 0) {
+               tclass = np->cork.tclass;
+               if (tclass < 0)
+                       tclass = 0;
+       }
 
        if (msg->msg_flags&MSG_CONFIRM)
                goto do_confirm;
@@ -832,9 +838,10 @@ back_from_confirm:
 
 do_append_data:
        up->len += ulen;
-       err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, 
sizeof(struct udphdr),
-                             hlimit, opt, fl, (struct rt6_info*)dst,
-                             corkreq ? msg->msg_flags|MSG_MORE : 
msg->msg_flags);
+       err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
+               sizeof(struct udphdr), hlimit, tclass, opt, fl,
+               (struct rt6_info*)dst,
+               corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
        if (err)
                udp_v6_flush_pending_frames(sk);
        else if (!corkreq)


[-- Attachment #2: rfc3542-2.patch --]
[-- Type: application/octet-stream, Size: 18092 bytes --]

diff -ruNp linux-2.6.11.10/include/linux/in6.h linux-2.6.11.10T3/include/linux/in6.h
--- linux-2.6.11.10/include/linux/in6.h	2005-05-16 10:51:43.000000000 -0700
+++ linux-2.6.11.10T3/include/linux/in6.h	2005-06-08 10:45:25.000000000 -0700
@@ -148,10 +148,10 @@ struct in6_flowlabel_req
  */
 
 #define IPV6_ADDRFORM		1
-#define IPV6_PKTINFO		2
-#define IPV6_HOPOPTS		3
-#define IPV6_DSTOPTS		4
-#define IPV6_RTHDR		5
+#define IPV6_2292PKTINFO	2
+#define IPV6_2292HOPOPTS	3
+#define IPV6_2292DSTOPTS	4
+#define IPV6_2292RTHDR		5
 #define IPV6_PKTOPTIONS		6
 #define IPV6_CHECKSUM		7
 #define IPV6_HOPLIMIT		8
@@ -184,6 +184,12 @@ struct in6_flowlabel_req
 
 #define IPV6_IPSEC_POLICY	34
 #define IPV6_XFRM_POLICY	35
+#define IPV6_RECVPKTINFO	36
+#define IPV6_RECVHOPLIMIT	37
+#define IPV6_RECVRTHDR		38
+#define IPV6_RECVHOPOPTS	39
+#define IPV6_RECVDSTOPTS	40
+#define IPV6_RECVTCLASS		41
 
 /*
  * Multicast:
@@ -198,4 +204,11 @@ struct in6_flowlabel_req
  * MCAST_MSFILTER		48
  */
 
+#define IPV6_PKTINFO		49
+#define IPV6_RTHDR		50
+#define IPV6_HOPOPTS		51
+#define IPV6_DSTOPTS		52
+#define IPV6_TCLASS		53
+#define IPV6_RTHDRDSTOPTS	54
+
 #endif
diff -ruNp linux-2.6.11.10/include/linux/ipv6.h linux-2.6.11.10T3/include/linux/ipv6.h
--- linux-2.6.11.10/include/linux/ipv6.h	2005-05-16 10:51:43.000000000 -0700
+++ linux-2.6.11.10T3/include/linux/ipv6.h	2005-06-07 15:10:28.000000000 -0700
@@ -221,7 +221,8 @@ struct ipv6_pinfo {
 				rxhlim:1,
 				hopopts:1,
 				dstopts:1,
-                                rxflow:1;
+                                rxflow:1,
+				rxtclass:1;
 		} bits;
 		__u8		all;
 	} rxopt;
@@ -231,7 +232,8 @@ struct ipv6_pinfo {
 	                        recverr:1,
 	                        sndflow:1,
 				pmtudisc:2,
-				ipv6only:1;
+				ipv6only:1,
+				rfc2292:1;
 
 	struct ipv6_mc_socklist	*ipv6_mc_list;
 	struct ipv6_ac_socklist	*ipv6_ac_list;
@@ -244,6 +246,7 @@ struct ipv6_pinfo {
 		struct ipv6_txoptions *opt;
 		struct rt6_info	*rt;
 		int hop_limit;
+		int tclass;
 	} cork;
 };
 
diff -ruNp linux-2.6.11.10/include/net/ipv6.h linux-2.6.11.10T3/include/net/ipv6.h
--- linux-2.6.11.10/include/net/ipv6.h	2005-05-16 10:51:49.000000000 -0700
+++ linux-2.6.11.10T3/include/net/ipv6.h	2005-05-24 14:57:23.000000000 -0700
@@ -347,6 +347,7 @@ extern int			ip6_append_data(struct sock
 						int length,
 						int transhdrlen,
 		      				int hlimit,
+		      				int tclass,
 						struct ipv6_txoptions *opt,
 						struct flowi *fl,
 						struct rt6_info *rt,
diff -ruNp linux-2.6.11.10/include/net/transp_v6.h linux-2.6.11.10T3/include/net/transp_v6.h
--- linux-2.6.11.10/include/net/transp_v6.h	2005-05-16 10:51:51.000000000 -0700
+++ linux-2.6.11.10T3/include/net/transp_v6.h	2005-05-24 14:04:11.000000000 -0700
@@ -37,7 +37,7 @@ extern int			datagram_recv_ctl(struct so
 extern int			datagram_send_ctl(struct msghdr *msg,
 						  struct flowi *fl,
 						  struct ipv6_txoptions *opt,
-						  int *hlimit);
+						  int *hlimit, int *tclass);
 
 #define		LOOPBACK4_IPV6		__constant_htonl(0x7f000006)
 
diff -ruNp linux-2.6.11.10/net/ipv6/datagram.c linux-2.6.11.10T3/net/ipv6/datagram.c
--- linux-2.6.11.10/net/ipv6/datagram.c	2005-05-16 10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/datagram.c	2005-06-08 11:29:31.000000000 -0700
@@ -381,13 +381,19 @@ int datagram_recv_ctl(struct sock *sk, s
 
 		src_info.ipi6_ifindex = opt->iif;
 		ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
-		put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
+		put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292PKTINFO :
+			IPV6_PKTINFO, sizeof(src_info), &src_info);
 	}
 
 	if (np->rxopt.bits.rxhlim) {
 		int hlim = skb->nh.ipv6h->hop_limit;
 		put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
 	}
+	if (np->rxopt.bits.rxtclass) {
+		u8 tclass = (skb->nh.ipv6h->priority << 4) |
+			((skb->nh.ipv6h->flow_lbl[0]>>4) & 0xf);
+		put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
+	}
 
 	if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
 		u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
@@ -395,26 +401,30 @@ int datagram_recv_ctl(struct sock *sk, s
 	}
 	if (np->rxopt.bits.hopopts && opt->hop) {
 		u8 *ptr = skb->nh.raw + opt->hop;
-		put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
+		put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292HOPOPTS :
+			IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
 	}
 	if (np->rxopt.bits.dstopts && opt->dst0) {
 		u8 *ptr = skb->nh.raw + opt->dst0;
-		put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+		put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292DSTOPTS :
+			IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
 	}
 	if (np->rxopt.bits.srcrt && opt->srcrt) {
 		struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
-		put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
+		put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292RTHDR :
+			IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
 	}
 	if (np->rxopt.bits.dstopts && opt->dst1) {
 		u8 *ptr = skb->nh.raw + opt->dst1;
-		put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+		put_cmsg(msg, SOL_IPV6, np->rfc2292 ? IPV6_2292DSTOPTS :
+			IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
 	}
 	return 0;
 }
 
 int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
 		      struct ipv6_txoptions *opt,
-		      int *hlimit)
+		      int *hlimit, int *tclass)
 {
 	struct in6_pktinfo *src_info;
 	struct cmsghdr *cmsg;
@@ -436,6 +446,7 @@ int datagram_send_ctl(struct msghdr *msg
 			continue;
 
 		switch (cmsg->cmsg_type) {
+		case IPV6_2292PKTINFO:
  		case IPV6_PKTINFO:
  			if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
 				err = -EINVAL;
@@ -491,6 +502,7 @@ int datagram_send_ctl(struct msghdr *msg
 			fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);
 			break;
 
+		case IPV6_2292HOPOPTS:
 		case IPV6_HOPOPTS:
                         if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
 				err = -EINVAL;
@@ -511,6 +523,7 @@ int datagram_send_ctl(struct msghdr *msg
 			opt->hopopt = hdr;
 			break;
 
+		case IPV6_2292DSTOPTS:
 		case IPV6_DSTOPTS:
                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
 				err = -EINVAL;
@@ -535,6 +548,7 @@ int datagram_send_ctl(struct msghdr *msg
 			opt->dst1opt = hdr;
 			break;
 
+		case IPV6_2292RTHDR:
 		case IPV6_RTHDR:
                         if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
 				err = -EINVAL;
@@ -587,6 +601,15 @@ int datagram_send_ctl(struct msghdr *msg
 			*hlimit = *(int *)CMSG_DATA(cmsg);
 			break;
 
+		case IPV6_TCLASS:
+			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+				err = -EINVAL;
+				goto exit_f;
+			}
+
+			*tclass = *(int *)CMSG_DATA(cmsg);
+			break;
+
 		default:
 			LIMIT_NETDEBUG(
 				printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type));
diff -ruNp linux-2.6.11.10/net/ipv6/icmp.c linux-2.6.11.10T3/net/ipv6/icmp.c
--- linux-2.6.11.10/net/ipv6/icmp.c	2005-05-16 10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/icmp.c	2005-05-24 15:05:14.000000000 -0700
@@ -287,7 +287,7 @@ void icmpv6_send(struct sk_buff *skb, in
 	int iif = 0;
 	int addr_type = 0;
 	int len;
-	int hlimit;
+	int hlimit, tclass;
 	int err = 0;
 
 	if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -381,6 +381,9 @@ void icmpv6_send(struct sk_buff *skb, in
 		hlimit = np->hop_limit;
 	if (hlimit < 0)
 		hlimit = dst_metric(dst, RTAX_HOPLIMIT);
+	tclass = np->cork.tclass;
+	if (tclass < 0)
+		tclass = 0;
 
 	msg.skb = skb;
 	msg.offset = skb->nh.raw - skb->data;
@@ -398,7 +401,7 @@ void icmpv6_send(struct sk_buff *skb, in
 	err = ip6_append_data(sk, icmpv6_getfrag, &msg,
 			      len + sizeof(struct icmp6hdr),
 			      sizeof(struct icmp6hdr),
-			      hlimit, NULL, &fl, (struct rt6_info*)dst,
+			      hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
 			      MSG_DONTWAIT);
 	if (err) {
 		ip6_flush_pending_frames(sk);
@@ -432,6 +435,7 @@ static void icmpv6_echo_reply(struct sk_
 	struct dst_entry *dst;
 	int err = 0;
 	int hlimit;
+	int tclass;
 
 	saddr = &skb->nh.ipv6h->daddr;
 
@@ -467,15 +471,18 @@ static void icmpv6_echo_reply(struct sk_
 		hlimit = np->hop_limit;
 	if (hlimit < 0)
 		hlimit = dst_metric(dst, RTAX_HOPLIMIT);
+	tclass = np->cork.tclass;
+	if (tclass < 0)
+		tclass = 0;
 
 	idev = in6_dev_get(skb->dev);
 
 	msg.skb = skb;
 	msg.offset = 0;
 
-	err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
-				sizeof(struct icmp6hdr), hlimit, NULL, &fl,
-				(struct rt6_info*)dst, MSG_DONTWAIT);
+	err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len +
+		sizeof(struct icmp6hdr), sizeof(struct icmp6hdr), hlimit,
+		tclass, NULL, &fl, (struct rt6_info*)dst, MSG_DONTWAIT);
 
 	if (err) {
 		ip6_flush_pending_frames(sk);
diff -ruNp linux-2.6.11.10/net/ipv6/ip6_flowlabel.c linux-2.6.11.10T3/net/ipv6/ip6_flowlabel.c
--- linux-2.6.11.10/net/ipv6/ip6_flowlabel.c	2005-05-16 10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/ip6_flowlabel.c	2005-05-24 14:04:28.000000000 -0700
@@ -311,7 +311,7 @@ fl_create(struct in6_flowlabel_req *freq
 		msg.msg_control = (void*)(fl->opt+1);
 		flowi.oif = 0;
 
-		err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk);
+		err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
 		if (err)
 			goto done;
 		err = -EINVAL;
diff -ruNp linux-2.6.11.10/net/ipv6/ip6_output.c linux-2.6.11.10T3/net/ipv6/ip6_output.c
--- linux-2.6.11.10/net/ipv6/ip6_output.c	2005-05-16 10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/ip6_output.c	2005-05-24 14:58:51.000000000 -0700
@@ -211,7 +211,7 @@ int ip6_xmit(struct sock *sk, struct sk_
 	struct ipv6hdr *hdr;
 	u8  proto = fl->proto;
 	int seg_len = skb->len;
-	int hlimit;
+	int hlimit, tclass;
 	u32 mtu;
 
 	if (opt) {
@@ -253,6 +253,13 @@ int ip6_xmit(struct sock *sk, struct sk_
 		hlimit = np->hop_limit;
 	if (hlimit < 0)
 		hlimit = dst_metric(dst, RTAX_HOPLIMIT);
+	tclass = -1;
+	if (np)
+		tclass = np->cork.tclass;
+	if (tclass < 0)
+		tclass = 0;
+	hdr->priority = (np->cork.tclass>>4) &0xf;
+	hdr->flow_lbl[0] |= (np->cork.tclass & 0xf)<<4;
 
 	hdr->payload_len = htons(seg_len);
 	hdr->nexthdr = proto;
@@ -806,10 +813,11 @@ out_err_release:
 	return err;
 }
 
-int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
-		    void *from, int length, int transhdrlen,
-		    int hlimit, struct ipv6_txoptions *opt, struct flowi *fl, struct rt6_info *rt,
-		    unsigned int flags)
+int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+	int offset, int len, int odd, struct sk_buff *skb),
+	void *from, int length, int transhdrlen,
+	int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
+	struct rt6_info *rt, unsigned int flags)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
@@ -847,6 +855,7 @@ int ip6_append_data(struct sock *sk, int
 		np->cork.rt = rt;
 		inet->cork.fl = *fl;
 		np->cork.hop_limit = hlimit;
+		np->cork.tclass = tclass;
 		inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst);
 		inet->cork.length = 0;
 		sk->sk_sndmsg_page = NULL;
@@ -1130,6 +1139,10 @@ int ip6_push_pending_frames(struct sock 
 	
 	*(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
 
+	/* traffic class */
+	hdr->priority = (np->cork.tclass>>4) & 0xf;
+	hdr->flow_lbl[0] |= (np->cork.tclass & 0xf)<<4;
+
 	if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
 		hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 	else
diff -ruNp linux-2.6.11.10/net/ipv6/ipv6_sockglue.c linux-2.6.11.10T3/net/ipv6/ipv6_sockglue.c
--- linux-2.6.11.10/net/ipv6/ipv6_sockglue.c	2005-05-16 10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/ipv6_sockglue.c	2005-06-08 11:06:47.000000000 -0700
@@ -115,6 +115,15 @@ extern int ip6_mc_msfilter(struct sock *
 extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
 	struct group_filter __user *optval, int __user *optlen);
 
+/*
+ * warn of obsolete RFC 2292 socket API use
+ */
+static void warn2292(char *optname)
+{
+	printk(KERN_WARNING "process '%s' is using obsolete %s socket option\n",
+		current->comm, optname);
+}
+
 
 int ipv6_setsockopt(struct sock *sk, int level, int optname,
 		    char __user *optval, int optlen)
@@ -208,33 +217,53 @@ int ipv6_setsockopt(struct sock *sk, int
 		retv = 0;
 		break;
 
-	case IPV6_PKTINFO:
+	case IPV6_2292PKTINFO:
+		warn2292("IPV6_PKTINFO");
+	case IPV6_RECVPKTINFO:
+		np->rfc2292 = optname == IPV6_2292PKTINFO;
 		np->rxopt.bits.rxinfo = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_HOPLIMIT:
+		warn2292("IPV6_HOPLIMIT");
+	case IPV6_RECVHOPLIMIT:
+		np->rfc2292 = optname == IPV6_HOPLIMIT;
 		np->rxopt.bits.rxhlim = valbool;
 		retv = 0;
 		break;
 
-	case IPV6_RTHDR:
+	case IPV6_2292RTHDR:
+		warn2292("IPV6_RTHDR");
+	case IPV6_RECVRTHDR:
 		if (val < 0 || val > 2)
 			goto e_inval;
+		np->rfc2292 = optname == IPV6_2292RTHDR;
 		np->rxopt.bits.srcrt = val;
 		retv = 0;
 		break;
 
-	case IPV6_HOPOPTS:
+	case IPV6_2292HOPOPTS:
+		warn2292("IPV6_HOPOPTS");
+	case IPV6_RECVHOPOPTS:
+		np->rfc2292 = optname == IPV6_2292HOPOPTS;
 		np->rxopt.bits.hopopts = valbool;
 		retv = 0;
 		break;
 
-	case IPV6_DSTOPTS:
+	case IPV6_2292DSTOPTS:
+		warn2292("IPV6_DSTOPTS");
+	case IPV6_RECVDSTOPTS:
+		np->rfc2292 = optname == IPV6_2292DSTOPTS;
 		np->rxopt.bits.dstopts = valbool;
 		retv = 0;
 		break;
 
+	case IPV6_RECVTCLASS:
+		np->rxopt.bits.rxtclass = valbool;
+		retv = 0;
+		break;
+
 	case IPV6_FLOWINFO:
 		np->rxopt.bits.rxflow = valbool;
 		retv = 0;
@@ -274,7 +303,7 @@ int ipv6_setsockopt(struct sock *sk, int
 		msg.msg_controllen = optlen;
 		msg.msg_control = (void*)(opt+1);
 
-		retv = datagram_send_ctl(&msg, &fl, opt, &junk);
+		retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
 		if (retv)
 			goto done;
 update:
@@ -620,26 +649,45 @@ int ipv6_getsockopt(struct sock *sk, int
 		val = np->ipv6only;
 		break;
 
-	case IPV6_PKTINFO:
+	case IPV6_2292PKTINFO:
+		warn2292("IPV6_PKTINFO");
+	case IPV6_RECVPKTINFO:
+		np->rfc2292 = optname == IPV6_2292PKTINFO;
 		val = np->rxopt.bits.rxinfo;
 		break;
 
 	case IPV6_HOPLIMIT:
+		warn2292("IPV6_HOPLIMIT");
+	case IPV6_RECVHOPLIMIT:
+		np->rfc2292 = optname == IPV6_HOPLIMIT;
 		val = np->rxopt.bits.rxhlim;
 		break;
 
-	case IPV6_RTHDR:
+	case IPV6_2292RTHDR:
+		warn2292("IPV6_RTHDR");
+	case IPV6_RECVRTHDR:
+		np->rfc2292 = optname == IPV6_2292RTHDR;
 		val = np->rxopt.bits.srcrt;
 		break;
 
-	case IPV6_HOPOPTS:
+	case IPV6_2292HOPOPTS:
+		warn2292("IPV6_HOPOPTS");
+	case IPV6_RECVHOPOPTS:
+		np->rfc2292 = optname == IPV6_2292HOPOPTS;
 		val = np->rxopt.bits.hopopts;
 		break;
 
-	case IPV6_DSTOPTS:
+	case IPV6_2292DSTOPTS:
+		warn2292("IPV6_DSTOPTS");
+	case IPV6_RECVDSTOPTS:
+		np->rfc2292 = optname == IPV6_2292DSTOPTS;
 		val = np->rxopt.bits.dstopts;
 		break;
 
+	case IPV6_RECVTCLASS:
+		val = np->rxopt.bits.rxtclass;
+		break;
+
 	case IPV6_FLOWINFO:
 		val = np->rxopt.bits.rxflow;
 		break;
diff -ruNp linux-2.6.11.10/net/ipv6/raw.c linux-2.6.11.10T3/net/ipv6/raw.c
--- linux-2.6.11.10/net/ipv6/raw.c	2005-05-16 10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/raw.c	2005-05-24 15:09:42.000000000 -0700
@@ -617,6 +617,7 @@ static int rawv6_sendmsg(struct kiocb *i
 	struct flowi fl;
 	int addr_len = msg->msg_namelen;
 	int hlimit = -1;
+	int tclass = -1;
 	u16 proto;
 	int err;
 
@@ -702,7 +703,7 @@ static int rawv6_sendmsg(struct kiocb *i
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 		opt->tot_len = sizeof(struct ipv6_txoptions);
 
-		err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+		err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
@@ -758,6 +759,12 @@ static int rawv6_sendmsg(struct kiocb *i
 			hlimit = dst_metric(dst, RTAX_HOPLIMIT);
 	}
 
+	if (tclass < 0) {
+		tclass = np->cork.tclass;
+		if (tclass < 0)
+			tclass = 0;
+	}
+
 	if (msg->msg_flags&MSG_CONFIRM)
 		goto do_confirm;
 
@@ -766,8 +773,9 @@ back_from_confirm:
 		err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags);
 	} else {
 		lock_sock(sk);
-		err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0,
-					hlimit, opt, &fl, (struct rt6_info*)dst, msg->msg_flags);
+		err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
+			len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
+			msg->msg_flags);
 
 		if (err)
 			ip6_flush_pending_frames(sk);
diff -ruNp linux-2.6.11.10/net/ipv6/udp.c linux-2.6.11.10T3/net/ipv6/udp.c
--- linux-2.6.11.10/net/ipv6/udp.c	2005-05-16 10:52:00.000000000 -0700
+++ linux-2.6.11.10T3/net/ipv6/udp.c	2005-05-24 15:11:58.000000000 -0700
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *i
 	int addr_len = msg->msg_namelen;
 	int ulen = len;
 	int hlimit = -1;
+	int tclass = -1;
 	int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
 	int err;
 
@@ -758,7 +759,7 @@ do_udp_sendmsg:
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 		opt->tot_len = sizeof(*opt);
 
-		err = datagram_send_ctl(msg, fl, opt, &hlimit);
+		err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
@@ -812,6 +813,11 @@ do_udp_sendmsg:
 		if (hlimit < 0)
 			hlimit = dst_metric(dst, RTAX_HOPLIMIT);
 	}
+	if (tclass < 0) {
+		tclass = np->cork.tclass;
+		if (tclass < 0)
+			tclass = 0;
+	}
 
 	if (msg->msg_flags&MSG_CONFIRM)
 		goto do_confirm;
@@ -832,9 +838,10 @@ back_from_confirm:
 
 do_append_data:
 	up->len += ulen;
-	err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr),
-			      hlimit, opt, fl, (struct rt6_info*)dst,
-			      corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
+	err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
+		sizeof(struct udphdr), hlimit, tclass, opt, fl,
+		(struct rt6_info*)dst,
+		corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
 	if (err)
 		udp_v6_flush_pending_frames(sk);
 	else if (!corkreq)

^ permalink raw reply

* Re: netdev munching messages again?
From: Ralf Baechle @ 2005-06-08 17:28 UTC (permalink / raw)
  To: Thomas Graf; +Cc: jamal, David S. Miller, netdev
In-Reply-To: <20050608161314.GM20969@postel.suug.ch>

On Wed, Jun 08, 2005 at 06:13:14PM +0200, Thomas Graf wrote:

> * Ralf Baechle <20050608160444.GA17777@linux-mips.org> 2005-06-08 17:04
> > Turns out that Thomas Graf's Email was intercepted by the spam filter,
> > so I've tweaked the filter setup a bit - probably at the price of
> > sacrificing some of the filter's effectivity.
> 
> Can you tell me why it was filtered? It might be a problem with my
> patch script which I could fix on my side. How much work would it
> be to whitelist a few people?

Whitelists tend to be problematic due to the enormous amounts of spam
and malware emails that come with forged email addresses.

I'll send you the rules in question and the original spamyness scores they
did compute in separate email, it's somewhat bigish.

> The weird thing is that patches 6-7 which could not be delivered
> immediately due to connection refused from oss.sgi.com came through
> fine.

Whatever it was, it was probably a separate issue from this spamfilter
faux-pas.  Note there is a firewall in front of oss.sgi.com which will
accept the SMTP TCP connection only to drop the connection shortly after
if it can't build a connection to the "real" oss.  So if you only get a
connection refused message when telneting to oss it really means the
firewall had some issues.  Unfortunately I don't have any control over
it, if I had I'd replace it with a nice patchcable ;-)

  Ralf

^ permalink raw reply

* Re: ipw2100: firmware problem
From: James Ketrenos @ 2005-06-08 17:10 UTC (permalink / raw)
  To: Denis Vlasenko
  Cc: Pavel Machek, Jeff Garzik, Netdev list, kernel list,
	James P. Ketrenos
In-Reply-To: <200506081744.20687.vda@ilport.com.ua>

Denis Vlasenko wrote:

>My position is that wifi drivers must start up in an "OFF" mode.
>Do not send anything. Do not join APs or start IBSS.
>Thus, no need to load fw in early boot.
>  
>
This should be an option for the user if that is the desired behavior. 
We support that with the ipw2100 and ipw2200 projects via module
parameters to disable the radio during module load.  Having a standard
module parameter for wireless drivers would be nice.

My approach is to make the driver so it supports as many usage models as
possible, leaving policy to other components of the system.  If the user
wants it to scan and associate immediately, that should be supported. 
Likewise if they want the module to be loaded w/ the radio off, they can
do that as well.

Since most (if not all) laptops support an RF kill switch, I tend to
defer to the physical switch as the user's point of control and set the
driver defaults to try and use the radio if it is enabled.

James

^ permalink raw reply

* Re: ipw2100: firmware problem
From: James Ketrenos @ 2005-06-08 16:58 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Jeff Garzik, Netdev list, kernel list, James P. Ketrenos
In-Reply-To: <20050608142310.GA2339@elf.ucw.cz>

Pavel Machek wrote:

>Hi!
>
>I'm fighting with firmware problem: if ipw2100 is compiled into
>kernel, it is loaded while kernel boots and firmware loader is not yet
>available. That leads to uninitialized (=> useless) adapter.
>  
>
We've been looking into whether the initrd can have the firmware affixed
to the end w/ some magic bytes to identify it.  If it works, enhancing
the request_firmware to support both hotplug and an initrd approach may
be reasonable.

>What's the prefered way to solve this one? Only load firmware when
>user does ifconfig eth1 up? [It is wifi, it looks like it would be
>better to start firmware sooner so that it can associate to the
>AP...].
>  
>
The debate goes back and forth on whether devices should come up only
after they are told, or initialize and start looking for a network as
soon as the module is loaded.

I lean more toward having the driver just do what it is told, defaulting
to trying to scan and associate so link is ready as soon as possible. 
We've added module parameters to change that behavior (disable and
associate for the ipw2100).

James

^ permalink raw reply

* Re: ipw2100: firmware problem
From: Pavel Machek @ 2005-06-08 16:29 UTC (permalink / raw)
  To: Jirka Bohac
  Cc: Denis Vlasenko, Pavel Machek, Jeff Garzik, Netdev list,
	kernel list
In-Reply-To: <20050608145653.GA8844@dwarf.suse.cz>

Hi!

> > Do you want to associate to an AP when your kernel boots,
> > _before_ any iwconfig had a chance to configure anything?
> > That's strange.
> > 
> > My position is that wifi drivers must start up in an "OFF" mode.
> > Do not send anything. Do not join APs or start IBSS.
> 
> Agreed.

Me too ;-).

> > Thus, no need to load fw in early boot.
> 
> I don't think this is true. Loading the firmware on the first
> "ifconfig up" is problematic. Often, people want to rename the
> device from ethX/wlanX/... to something stable. This is usually
> based on the adapter's MAC address, which is not visible until
> the firmware is loaded.
> 
> Prism54 does it this way and it really sucks. You need to bring
> the adapter up to load the firmware, then bring it back down,
> rename it, and bring it up again.
> 
> Denis: any plans for this to be fixed?
> 
> I agree that drivers should initialize the adapter in the OFF
> state, but the firmware needs to be loaded earlier than the
> first ifconfig up.
> 
> How about loading the firmware when the first ioctl touches the
> device? This way, it would get loaded just before the MAC address
> is retrieved.

Thats really ugly :-(.

				Pavel
-- 
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms         

^ permalink raw reply

* Kernel BUG at "net/ipv4/tcp_output.c":928
From: belyshev @ 2005-06-08 16:16 UTC (permalink / raw)
  To: netdev
In-Reply-To: <56hdg93rxb.fsf@depni.sinp.msu.ru>


>Seems that this oops happens only if using hostap.

Apparently this has nothing to do with hostap, as I was able to reproduce this
without it:

----------- [cut here ] --------- [please bite here ] ---------
Kernel BUG at "net/ipv4/tcp_output.c":928
invalid operand: 0000 [1] 
CPU 0 
Modules linked in:
Pid: 2854, comm: nc Not tainted 2.6.12-rc6-mm1-gcc34
RIP: 0010:[<ffffffff803dad47>] <ffffffff803dad47>{tcp_tso_should_defer+55}
RSP: 0018:ffff810018b29c08  EFLAGS: 00010246
RAX: 000000000000002c RBX: ffff81001e0cdd40 RCX: 0000000005a80100
RDX: ffff81001e0cdd40 RSI: ffff81001ed44040 RDI: 0000000000000002
RBP: ffff81001ed44040 R08: 0000000000000000 R09: ffff810018b29d60
R10: 0000000000000002 R11: ffffffff8018c200 R12: ffff81001ed44040
R13: ffff81001ed44040 R14: 000000000000002d R15: 00000000000005a8
FS:  00002aaaaae00c80(0000) GS:ffffffff8081c840(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00000000007bd0d8 CR3: 0000000018b7d000 CR4: 00000000000006e0
Process nc (pid: 2854, threadinfo ffff810018b28000, task ffff81001f704f70)
Stack: ffff81001e0cdd40 ffffffff803daea4 ffff81001ed440d8 0000000000000296 
       0000000100000001 ffff81001ed44040 ffff81001ed44040 0000000000000000 
       0000000000000000 ffff81001a824088 
Call Trace:<ffffffff803daea4>{tcp_write_xmit+212} <ffffffff803db1b9>{__tcp_push_pending_frames+41}
       <ffffffff803d2153>{tcp_close+595} <ffffffff803ed8b8>{inet_release+88}
       <ffffffff8038ac01>{sock_release+33} <ffffffff8038b8e5>{sock_close+53}
       <ffffffff80173972>{__fput+194} <ffffffff8017222e>{filp_close+110}
       <ffffffff801334f3>{put_files_struct+115} <ffffffff80133da4>{do_exit+484}
       <ffffffff8013b745>{__dequeue_signal+501} <ffffffff8013477f>{do_group_exit+159}
       <ffffffff8013d267>{get_signal_to_deliver+1239} <ffffffff8010dd52>{do_signal+162}
       <ffffffff8017e3a7>{pipe_readv+823} <ffffffff80486968>{cond_resched+56}
       <ffffffff801978a1>{inotify_inode_queue_event+49} <ffffffff80145b00>{autoremove_wake_function+0}
       <ffffffff80172bcd>{vfs_write+317} <ffffffff8010e95b>{sysret_signal+28}
       <ffffffff8010ec43>{ptregscall_common+103} 

Code: 0f 0b 56 a9 4e 80 ff ff ff ff a0 03 44 8b 86 14 03 00 00 44 
RIP <ffffffff803dad47>{tcp_tso_should_defer+55} RSP <ffff810018b29c08>
 <1>Fixing recursive fault but reboot is needed!

^ permalink raw reply

* Re: netdev munching messages again?
From: Thomas Graf @ 2005-06-08 16:13 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: jamal, David S. Miller, netdev
In-Reply-To: <20050608160444.GA17777@linux-mips.org>

* Ralf Baechle <20050608160444.GA17777@linux-mips.org> 2005-06-08 17:04
> Turns out that Thomas Graf's Email was intercepted by the spam filter,
> so I've tweaked the filter setup a bit - probably at the price of
> sacrificing some of the filter's effectivity.

Can you tell me why it was filtered? It might be a problem with my
patch script which I could fix on my side. How much work would it
be to whitelist a few people?

The weird thing is that patches 6-7 which could not be delivered
immediately due to connection refused from oss.sgi.com came through
fine.

^ permalink raw reply

* Re: netdev munching messages again?
From: Ralf Baechle @ 2005-06-08 16:04 UTC (permalink / raw)
  To: jamal; +Cc: Thomas Graf, David S. Miller, netdev
In-Reply-To: <1118238264.6382.43.camel@localhost.localdomain>

On Wed, Jun 08, 2005 at 09:44:23AM -0400, jamal wrote:

> I thought netdev just picks on me ;-> My stoopid ISP as well
> as oss.sgi.com have some "clever" (read: questionable) ways 
> of delivering email which violates end to end semantics of SMTP.
> I too noticed some emails were swallowed in the last 1-2 days. I know
> from past experience in fact they will never be seen again;->
> Or someone, who doesnt look at the headers, will flame me for repeating
> what has already been discussed and agreed on (has happened to me at
> least 5 times on netdev ;->).
> 
> It's quiet ironic when packets delivered over TCP dont make it to the
> remote end, even when the app tries to help in reliable delivery;->
> 
> CCing El-sido Bacchus.

Turns out that Thomas Graf's Email was intercepted by the spam filter,
so I've tweaked the filter setup a bit - probably at the price of
sacrificing some of the filter's effectivity.

It unfortunately has become totally impractical to walk through the
hundreds of moderator emails every day due to the volume, so I need to
rely on people to report about such problem to postmaster@oss.sgi.com
or me directly via email or irc.

As for resending messages, due to people doing stupid things such as
restoring their mail and news spools oss is keeping a non-expiring list
of message IDs.  However only non-spam message IDs are being recorded.

  Ralf

^ permalink raw reply

* Re: ipw2100: firmware problem
From: Jiri Benc @ 2005-06-08 15:23 UTC (permalink / raw)
  To: abonilla
  Cc: 'Denis Vlasenko', 'Pavel Machek',
	'Jeff Garzik', 'Netdev list',
	'kernel list', 'James P. Ketrenos'
In-Reply-To: <002901c56c3b$8216cdd0$600cc60a@amer.sykes.com>

On Wed, 8 Jun 2005 09:05:27 -0600, Alejandro Bonilla wrote:
> 	I might be lost here but... How is the firmware loaded when using the
> ipw2100-1.0.0/patches Kernel patch?

It is loaded by request_firmware() during initialization of the adapter.
That doesn't work, as at that time no hotplug binary can be executed (we
are talking about ipw2100 built in the kernel, not built as a module).

> Currently, when we install the driver, it associates to any open network on
> boot. This is good, cause we don't want to be typing the commands all the
> time just to associate. It works this way now and is pretty nice.

It sounds very dangerous to me.

> So, to scan a network, I would have to do ifconfig eth1 up ; iwlist eth1
> scan?

No. Driver should request the firmware when it is told to perform a scan.

> When moving from modes with the firmwares, would I have to do ifconfig eth1
> up ; iwconfig eth1 mode monitor? or would the firmware be loaded with
> iwconfig? Does it have that function?

Firmware can be loaded automatically by the driver when there is some
request from userspace and the firmware has not been loaded yet.


-- 
Jiri Benc
SUSE Labs

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox