* Re: RFC: NAPI packet weighting patch
From: Andi Kleen @ 2005-06-21 21:47 UTC (permalink / raw)
To: Rick Jones; +Cc: netdev, davem
In-Reply-To: <42B87ACF.3080800@hp.com>
Rick Jones <rick.jones2@hp.com> writes:
> > Actually, it has a _HUGE_ _HUGE_ impact. If you pass the big buffer
> > up, the receiving socket gets charged for the size of the huge buffer,
> > not for just the size of the packet contained within. This makes
> > sockets get overcharged for data reception, and it can cause all kinds
> > of performance problems.
>
> Then copy when the socket is about to fill with overhead bytes?
The stack has supported that since 2.4.
Mostly because it is the only sane way to handle devices with very big
MTU. But it turns off all kinds of fast paths before it happens, I
guess that is what David was refering too.
However I suspect the cut-off points with rx-copybreak in common driver
have been often tuned before that code was introduced and it might
be worth to do some retesting.
-Andi
^ permalink raw reply
* [patch,rfc] allow registration of multiple netpolls per interface
From: Jeff Moyer @ 2005-06-21 21:41 UTC (permalink / raw)
To: mpm; +Cc: netdev, netdev, linux-kernel
Hi,
This patch restores functionality that was removed when the recursive
->poll bug was fixed. Namely, it allows multiple netpoll clients to
register against the same network interface.
In order to put things into perspective, I'm going to provide some
background information. So, here is how things used to work:
Multiple users of the netpoll interface could register themselves to send
packets over the same interface. Any number of these netpoll clients could
register an rx_hook, as well. However, only the very first in the list
(hence the last one that registered), that matched the incoming interface,
would be called when a packet arrived. The reason for this was not design,
it was an oversight in the implementation. In practice, however, no one
ever stumbled over this. (There are more subtleties when dealing with
multiple rx_hooks registered to the same interface, but we'll ignore these,
since no one ever ran into such problems.)
Note that each netpoll client that registered an rx_hook was put on a
netpoll_rx_list. This list was protected by a spinlock, and so operations
which touched the rx routines would incur a locking penalty and a list
traversal. I am mentioning this because the list and associated lock were
removed when the code was refactored, and the patches I propose will
reintroduce the lock, but not the list.
Moving to what we have today:
Multiple netpoll clients can register to send packets over the same
interface. That's right, you can actually do this. However, there are
ugly side effects. Because we now have a pointer from the net_device to a
struct netpoll, the last netpoll client to register will be pointed to by
the net_device->np. What this means is that if you had two clients, the
first registers an rx_hook and the second does not, then the netpoll code
will not know that any device has actually registered an rx_hook (since the
np pointer in the struct net_device is overwritten)! As a result, no
incoming packets will be delivered to the registered rx routine. This is
clearly undesirable behaviour.
So what does the patch do?
I created a new structure:
struct netpoll_info {
spinlock_t poll_lock;
int poll_owner;
int rx_flags;
spinlock_t rx_lock;
struct netpoll *rx_np; /* netpoll that registered an rx_hook */
};
This is the structure which gets pointed to by the net_device. All of the
flags and locks which are specific to the INTERFACE go here. Any variables
which must be kept per struct netpoll were left in the struct netpoll. So
now, we have a cleaner separation of data and its scope.
Since we never really supported having more than one struct netpoll
register an rx_hook, I got rid of the rx_list. This is replaced by a
single pointer in the netpoll_info structure (np_rx). We still need to
protect addition or removal of the rx_np pointer, and so keep the lock
(rx_lock). There is one lock per struct net_device, and I am certain that
it will be 0 contention, as rx_np will only be changed during an insmod or
rmmod. If people think this would be a good rcu candidate, let me know and
I'll change it to use that locking scheme.
In the process of making these changes, I've fixed a couple other minor
bugs [1]. These fixes are included in this patch, but I will break them
out if people agree with this approach.
I have tested this by registering multiple netpoll clients, and verifying
that they both function properly. I have not yet tried registering an
rx_hook, but I believe the code should be sufficient to handle that case.
And so, here is the full patch. I'd appreciate comments. Once we've
reached consensus, I will resubmit as a patch series.
Oh, and I've cc'd both netdev@oss.sgi.com and @vger.kernel.org. Is it safe
to just use the vger list?
Thanks,
Jeff
[1] netpoll_poll_unlock unlocked and then set the poll_owner. I've
reversed the order of those operations. The netpoll_cleanup code could
dereference a null pointer, that was fixed by virtue of being very
different in the new case.
--- linux-2.6.12-rc6/net/core/netpoll.c.orig 2005-06-20 19:51:56.000000000 -0400
+++ linux-2.6.12-rc6/net/core/netpoll.c 2005-06-21 16:03:22.409620400 -0400
@@ -131,18 +131,19 @@ static int checksum_udp(struct sk_buff *
static void poll_napi(struct netpoll *np)
{
int budget = 16;
+ struct netpoll_info *npinfo = np->dev->npinfo;
if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
- np->poll_owner != smp_processor_id() &&
- spin_trylock(&np->poll_lock)) {
- np->rx_flags |= NETPOLL_RX_DROP;
+ npinfo->poll_owner != smp_processor_id() &&
+ spin_trylock(&npinfo->poll_lock)) {
+ npinfo->rx_flags |= NETPOLL_RX_DROP;
atomic_inc(&trapped);
np->dev->poll(np->dev, &budget);
atomic_dec(&trapped);
- np->rx_flags &= ~NETPOLL_RX_DROP;
- spin_unlock(&np->poll_lock);
+ npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+ spin_unlock(&npinfo->poll_lock);
}
}
@@ -245,6 +246,7 @@ repeat:
static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
{
int status;
+ struct netpoll_info *npinfo;
repeat:
if(!np || !np->dev || !netif_running(np->dev)) {
@@ -253,7 +255,8 @@ repeat:
}
/* avoid recursion */
- if(np->poll_owner == smp_processor_id() ||
+ npinfo = np->dev->npinfo;
+ if(npinfo->poll_owner == smp_processor_id() ||
np->dev->xmit_lock_owner == smp_processor_id()) {
if (np->drop)
np->drop(skb);
@@ -346,7 +349,15 @@ static void arp_reply(struct sk_buff *sk
int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
u32 sip, tip;
struct sk_buff *send_skb;
- struct netpoll *np = skb->dev->np;
+ struct netpoll *np;
+ struct netpoll_info *npinfo = skb->dev->npinfo;
+
+ if (!npinfo) return;
+
+ spin_lock_irqsave(&npinfo->rx_lock, flags);
+ if (npinfo->rx_np->dev == skb->dev)
+ np = npinfo->rx_np;
+ spin_unlock_irqrestore(&npinfo->rx_lock, flags);
if (!np) return;
@@ -429,9 +440,9 @@ int __netpoll_rx(struct sk_buff *skb)
int proto, len, ulen;
struct iphdr *iph;
struct udphdr *uh;
- struct netpoll *np = skb->dev->np;
+ struct netpoll *np = skb->dev->npinfo->rx_np;
- if (!np->rx_hook)
+ if (!np)
goto out;
if (skb->dev->type != ARPHRD_ETHER)
goto out;
@@ -611,9 +622,8 @@ int netpoll_setup(struct netpoll *np)
{
struct net_device *ndev = NULL;
struct in_device *in_dev;
-
- np->poll_lock = SPIN_LOCK_UNLOCKED;
- np->poll_owner = -1;
+ struct netpoll_info *npinfo;
+ unsigned long flags;
if (np->dev_name)
ndev = dev_get_by_name(np->dev_name);
@@ -624,7 +634,17 @@ int netpoll_setup(struct netpoll *np)
}
np->dev = ndev;
- ndev->np = np;
+ if (!ndev->npinfo) {
+ npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
+ if (!npinfo)
+ goto release;
+
+ npinfo->rx_np = NULL;
+ npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
+ npinfo->poll_owner = -1;
+ npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
+ } else
+ npinfo = ndev->npinfo;
if (!ndev->poll_controller) {
printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
@@ -692,13 +712,20 @@ int netpoll_setup(struct netpoll *np)
np->name, HIPQUAD(np->local_ip));
}
- if(np->rx_hook)
- np->rx_flags = NETPOLL_RX_ENABLED;
+ if(np->rx_hook) {
+ spin_lock_irqsave(&npinfo->rx_lock, flags);
+ npinfo->rx_flags |= NETPOLL_RX_ENABLED;
+ npinfo->rx_np = np;
+ spin_unlock_irqsave(&npinfo->rx_lock, flags);
+ }
+ /* last thing to do is link it to the net device structure */
+ ndev->npinfo = npinfo;
return 0;
release:
- ndev->np = NULL;
+ if (!ndev->npinfo)
+ kfree(npinfo);
np->dev = NULL;
dev_put(ndev);
return -1;
@@ -706,9 +733,17 @@ int netpoll_setup(struct netpoll *np)
void netpoll_cleanup(struct netpoll *np)
{
- if (np->dev)
- np->dev->np = NULL;
- dev_put(np->dev);
+ struct netpoll_info *npinfo;
+
+ if (np->dev) {
+ npinfo = np->dev->npinfo;
+ if (npinfo && npinfo->rx_np == np) {
+ npinfo->rx_np = NULL;
+ npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
+ }
+ dev_put(np->dev);
+ }
+
np->dev = NULL;
}
--- linux-2.6.12-rc6/net/core/dev.c.orig 2005-06-20 19:51:59.000000000 -0400
+++ linux-2.6.12-rc6/net/core/dev.c 2005-06-21 13:53:51.583407710 -0400
@@ -1656,6 +1656,7 @@ int netif_receive_skb(struct sk_buff *sk
unsigned short type;
/* if we've gotten here through NAPI, check netpoll */
+ /* how else can we get here? --phro */
if (skb->dev->poll && netpoll_rx(skb))
return NET_RX_DROP;
--- linux-2.6.12-rc6/include/linux/netpoll.h.orig 2005-06-20 19:51:47.000000000 -0400
+++ linux-2.6.12-rc6/include/linux/netpoll.h 2005-06-21 15:29:48.994422229 -0400
@@ -16,14 +16,19 @@ struct netpoll;
struct netpoll {
struct net_device *dev;
char dev_name[16], *name;
- int rx_flags;
void (*rx_hook)(struct netpoll *, int, char *, int);
void (*drop)(struct sk_buff *skb);
u32 local_ip, remote_ip;
u16 local_port, remote_port;
unsigned char local_mac[6], remote_mac[6];
+};
+
+struct netpoll_info {
spinlock_t poll_lock;
int poll_owner;
+ int rx_flags;
+ spinlock_t rx_lock;
+ struct netpoll *rx_np; /* netpoll that registered an rx_hook */
};
void netpoll_poll(struct netpoll *np);
@@ -39,22 +44,35 @@ void netpoll_queue(struct sk_buff *skb);
#ifdef CONFIG_NETPOLL
static inline int netpoll_rx(struct sk_buff *skb)
{
- return skb->dev->np && skb->dev->np->rx_flags && __netpoll_rx(skb);
+ struct netpoll_info *npinfo = skb->dev->npinfo;
+ unsigned long flags;
+ int ret = 0;
+
+ if (!npinfo || (!npinfo->rx_np && !npinfo->rx_flags))
+ return 0;
+
+ spin_lock_irqsave(&npinfo->rx_lock, flags);
+ /* check rx_flags again with the lock held */
+ if (npinfo->rx_flags && __netpoll_rx(skb))
+ ret = 1;
+ spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+
+ return ret;
}
static inline void netpoll_poll_lock(struct net_device *dev)
{
- if (dev->np) {
- spin_lock(&dev->np->poll_lock);
- dev->np->poll_owner = smp_processor_id();
+ if (dev->npinfo) {
+ spin_lock(&dev->npinfo->poll_lock);
+ dev->npinfo->poll_owner = smp_processor_id();
}
}
static inline void netpoll_poll_unlock(struct net_device *dev)
{
- if (dev->np) {
- spin_unlock(&dev->np->poll_lock);
- dev->np->poll_owner = -1;
+ if (dev->npinfo) {
+ dev->npinfo->poll_owner = -1;
+ spin_unlock(&dev->npinfo->poll_lock);
}
}
--- linux-2.6.12-rc6/include/linux/netdevice.h.orig 2005-06-20 20:26:21.000000000 -0400
+++ linux-2.6.12-rc6/include/linux/netdevice.h 2005-06-21 14:46:52.093190854 -0400
@@ -41,7 +41,7 @@
struct divert_blk;
struct vlan_group;
struct ethtool_ops;
-struct netpoll;
+struct netpoll_info;
/* source back-compat hooks */
#define SET_ETHTOOL_OPS(netdev,ops) \
( (netdev)->ethtool_ops = (ops) )
@@ -468,7 +468,7 @@ struct net_device
unsigned char *haddr);
int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
#ifdef CONFIG_NETPOLL
- struct netpoll *np;
+ struct netpoll_info *npinfo;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
void (*poll_controller)(struct net_device *dev);
^ permalink raw reply
* Re: RFC: NAPI packet weighting patch
From: David S. Miller @ 2005-06-21 20:55 UTC (permalink / raw)
To: rick.jones2
Cc: shemminger, mitch.a.williams, john.ronciak, mchan, hadi, buytenh,
jdmason, netdev, Robert.Olsson, ganesh.venkatesan,
jesse.brandeburg
In-Reply-To: <42B87ACF.3080800@hp.com>
From: Rick Jones <rick.jones2@hp.com>
Date: Tue, 21 Jun 2005 13:38:39 -0700
> > I highly recommend that this gets fixed.
>
> What is the cut-off point for the copy?
256 has been found to be a well functioning value to use.
^ permalink raw reply
* Re: [patch] devinet: cleanup if statements
From: David S. Miller @ 2005-06-21 20:48 UTC (permalink / raw)
To: pmeda; +Cc: jgarzik, akpm, netdev
In-Reply-To: <200506072032.NAA06207@allur.sanmateo.akamai.com>
From: pmeda@akamai.com
Date: Tue, 7 Jun 2005 13:32:44 -0700
> Cleanup the devinet if statements.
> - when there is no colon, interface name is same as device.
> - ifa_label is an array, not a pointer, and so can never be null.
>
> Signed-Off-by: Prasanna Meda <pmeda@akamai.com>
Ok, I can see how your first change is correct.
When there is a colon, we've modified ifr.ifr_name by
patching the ':' character to be a '\0'. This is for
the __dev_get_by_name() lookup.
After that lookup, we re-patch the ':' character back
into ifr.ifr_name. So indeed, always using the ifr_name
in that code block would be correct.
The second hunk of your patch seems to defeat the intention
of that code. I believe the idea is that if the label and
the device name differ, use the label.
This whole area is pretty messy, we should examine the true
intended semantics of the ifa_label stuff.
^ permalink raw reply
* Re: RFC: NAPI packet weighting patch
From: Rick Jones @ 2005-06-21 20:38 UTC (permalink / raw)
To: David S. Miller
Cc: shemminger, mitch.a.williams, john.ronciak, mchan, hadi, buytenh,
jdmason, netdev, Robert.Olsson, ganesh.venkatesan,
jesse.brandeburg
In-Reply-To: <20050621.132044.115910664.davem@davemloft.net>
David S. Miller wrote:
> From: Stephen Hemminger <shemminger@osdl.org>
> Date: Mon, 06 Jun 2005 21:53:32 -0700
>
>
>>I noticed that the tg3 driver copies packets less than a certain
>>threshold to a new buffer, but e1000 always passes the big buffer up
>>the stack. Could this be having an impact?
>
>
> I bet it does, this makes ACK processing a lot more expensive.
Why would ACK processing care about the size of the buffer containing the ACK
segment?
> And it
> is so much cheaper to just recycle the big buffer back to the chip
> if you copy to a small buffer, and it warms up the caches for the
> packet headers as a side effect as well.
I would think that the cache business would be a wash either way. With 64 byte
cache lines (128 in some cases) just accessing the link-level header has brought
the IP header into the cache, and probably the TCP header as well.
Isn't the decision point between the sum of allocating a small buffer and doing
the copy, versus allocating a new large buffer and (re)mapping it for DMA? I
guess that would come down to copy versus mapping overhead.
> Actually, it has a _HUGE_ _HUGE_ impact. If you pass the big buffer
> up, the receiving socket gets charged for the size of the huge buffer,
> not for just the size of the packet contained within. This makes
> sockets get overcharged for data reception, and it can cause all kinds
> of performance problems.
Then copy when the socket is about to fill with overhead bytes?
> I highly recommend that this gets fixed.
What is the cut-off point for the copy?
rick jones
^ permalink raw reply
* Re: RFC: NAPI packet weighting patch
From: David S. Miller @ 2005-06-21 20:37 UTC (permalink / raw)
To: gandalf
Cc: hadi, shemminger, mitch.a.williams, john.ronciak, mchan, buytenh,
jdmason, netdev, Robert.Olsson, ganesh.venkatesan,
jesse.brandeburg
In-Reply-To: <Pine.LNX.4.58.0506071351080.16594@tux.rsn.bth.se>
From: Martin Josefsson <gandalf@wlug.westbo.se>
Date: Tue, 7 Jun 2005 14:06:18 +0200 (CEST)
> One thing that jumps to mind is that e1000 starts at lastrxdescriptor+1
> and loops and checks the status of each descriptor and stops when it finds
> a descriptor that isn't finished. Another way to do it is to read out the
> current position of the ring and loop from lastrxdescriptor+1 up to the
> current position. Scott Feldman implemented this for TX and there it
> increased performance somewhat (discussed here on netdev some months ago).
> I wonder if it could also decrease RX latency, I mean, we have to get the
> cache miss sometime anyway.
>
> I havn't checked how tg3 does it.
I don't think this matters all that much. tg3 does loop on RX
producer index, so doesn't touch descriptors unless the RX producer
index states there is a ready packet there.
One thing I noticed with Super TSO testing is that e1000 has very
expensive TSO transmit processing. The big problem is the context
descriptor. This is 4 extra 32-bit words eaten up in the transmit
ring for every TSO packet. Whereas tg3 stores all the TSO offload
information directly in the normal TX descriptor (which is the
same size, 16 bytes, as the e1000 normal TX descriptor).
It accounts for a non-trivial amount of overhead. On my SunBlade1500
with Super TSO, e1000 transmitter eats %40 of CPU to fill a gigabit
pipe whereas tg3 takes %30. All of the extra time, based upon quick
scans of oprofile dumps, shows it in the e1000 driver.
Also, e1000 sends full MTU sized SKBs down into the stack even if the
packet is very small. This also hurts performance a lot. As
discussed elsewhere, it should use a "small packet" cut-off just like
other drivers do. If the RX frame is less than this cut-off value, a
new smaller sized SKB is allocated and the RX data copied into it.
The RX ring SKB is left in-place and given back to the chip.
My only guess is that the e1000 driver implemented things this way
to simplify the RX recycling logic. Well, it is an area ripe for
improvement in this driver :)
^ permalink raw reply
* Re: [PATCH]: Tigon3 new NAPI locking v2
From: David S. Miller @ 2005-06-21 20:21 UTC (permalink / raw)
To: gnb; +Cc: netdev, mchan
In-Reply-To: <1118139072.2198.119.camel@hole.melbourne.sgi.com>
From: Greg Banks <gnb@melbourne.sgi.com>
Date: Tue, 07 Jun 2005 20:11:12 +1000
> This patch seems to run well, so far without the lockup we saw
> with the first version. It really helps with irq fairness when
> we have lots of tg3 and Fibre Channel HBA interrupts going to the
> same CPU.
A belated thank you for testing Greg.
^ permalink raw reply
* Re: RFC: NAPI packet weighting patch
From: David S. Miller @ 2005-06-21 20:20 UTC (permalink / raw)
To: shemminger
Cc: mitch.a.williams, john.ronciak, mchan, hadi, buytenh, jdmason,
netdev, Robert.Olsson, ganesh.venkatesan, jesse.brandeburg
In-Reply-To: <42A5284C.3060808@osdl.org>
From: Stephen Hemminger <shemminger@osdl.org>
Date: Mon, 06 Jun 2005 21:53:32 -0700
> I noticed that the tg3 driver copies packets less than a certain
> threshold to a new buffer, but e1000 always passes the big buffer up
> the stack. Could this be having an impact?
I bet it does, this makes ACK processing a lot more expensive. And it
is so much cheaper to just recycle the big buffer back to the chip
if you copy to a small buffer, and it warms up the caches for the
packet headers as a side effect as well.
Actually, it has a _HUGE_ _HUGE_ impact. If you pass the big buffer
up, the receiving socket gets charged for the size of the huge buffer,
not for just the size of the packet contained within. This makes
sockets get overcharged for data reception, and it can cause all kinds
of performance problems.
I highly recommend that this gets fixed.
^ permalink raw reply
* Re: iptables bug
From: Stephen Jones @ 2005-06-21 19:21 UTC (permalink / raw)
To: Patrick McHardy
Cc: Andrew Morton, netdev, J.A. Magallon,
Netfilter Development Mailinglist, linux-kernel
In-Reply-To: <42B753A8.5050808@trash.net>
Patrick McHardy wrote:
> Andrew Morton wrote:
>
>>"J.A. Magallon" <jamagallon@able.es> wrote:
>>
>>
>>>Are there any known problems with iptables ?
>
>
> No known problems.
>
>
>>>I see strange things.
>>>When I use bittorrent (azureus or bittorrent-gui), at the same time as
>>>iptables (for nat and internet access for my ibook), when I stop a download
>>>or exit from one of this apps my external network goes down.
>>>I have tried the same without iptables loaded and it works fine.
I have observed this behavior on multiple machines, but I don't think it
is specifically an iptables "bug" or kernel "bug". Most of my
experience is with 2.4.x kernels, so I can't remark about the 2.6.x series.
The original poster didn't give enough info for me to correlate anything
with conviction, but, consulting the tea leaves :D I would venture to
guess that the machine that has the network "go down" has less than 128
MB of RAM and is probably running lower end NICs (i.e. 8139too).
There appears to be two or three issues interacting with one another in
these scenarios:
a.) The various Bit Torrent clients and their ilk can generate a
staggering number of conncurrent connections. This can quickly fill the
conntracks on machines with little RAM and cause problems.
b.) The lower end nics (either the hardware itself, or the drivers, I
don't know enough about how to isolate the two) do not appear to be able
to handle the massive number of interrupts that are generated in this
scenario.
c.) The problem is more likely to manifest on "fat pipe" connections (6
MB +)
I would also wager the problem goes away if the torrent clients are shut
down.
I would look there, if I hade the skills requried to tease out anything
useful :D
Various linux based firewall forums have posts describing the same
behavior as the OP of this thread.
Here is one relatively recent example:
http://community.smoothwall.org/forum/viewtopic.php?p=43812#43812
I hope that helps in some way!
>
>
> What exactly do you mean with "network goes down"? Can you find out
> where the packets disappear? Do they silently disappear, or do you get
> an error code from sendmsg? What about received packets?
>
> Regards
> Patrick
>
>
>
^ permalink raw reply
* Re: ipw2100: firmware problem
From: Simon Kelley @ 2005-06-21 8:46 UTC (permalink / raw)
To: Feyd
Cc: Jirka Bohac, Denis Vlasenko, Pavel Machek, Jeff Garzik,
Netdev list, kernel list
In-Reply-To: <20050621102921.5a8c953a@alfa.nmskb.cz>
Feyd wrote:
> On Tue, 21 Jun 2005 08:42:08 +0100
> Simon Kelley <simon@thekelleys.org.uk> wrote:
>
>
>>The atmel driver includes a small firmware stub which does nothing but
>>determine the MAC address, to solve this problem. This is compiled into
>
>
> Does it power-down the card after reading the MAC?
>
Yes, it loads the special firmware, runs it to get the MAC, and then
returns the card to quiesent state, ready for the real firmware load
which happens at device open time.
Cheers,
Simon.
^ permalink raw reply
* Re: ipw2100: firmware problem
From: Feyd @ 2005-06-21 8:29 UTC (permalink / raw)
To: Simon Kelley
Cc: Jirka Bohac, Denis Vlasenko, Pavel Machek, Jeff Garzik,
Netdev list, kernel list
In-Reply-To: <42B7C4D0.9070809@thekelleys.org.uk>
On Tue, 21 Jun 2005 08:42:08 +0100
Simon Kelley <simon@thekelleys.org.uk> wrote:
> The atmel driver includes a small firmware stub which does nothing but
> determine the MAC address, to solve this problem. This is compiled into
Does it power-down the card after reading the MAC?
Feyd
^ permalink raw reply
* Re: ipw2100: firmware problem
From: Simon Kelley @ 2005-06-21 7:42 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>
Jirka Bohac wrote:
> On Wed, Jun 08, 2005 at 05:44:20PM +0300, Denis Vlasenko wrote:
>
>>On Wednesday 08 June 2005 17:23, Pavel Machek wrote:
>>
>>>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...].
>>
>>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.
>
>
>>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.
>
The atmel driver includes a small firmware stub which does nothing but
determine the MAC address, to solve this problem. This is compiled into
the driver and so doesn't depend on request_firmware(). The stub was
created by reverse engineering the card and is GPL, so there's no
problem including it in the kernel.
This is not a general solution, since it depends on the ability to
create such MAC reader firmware, but it might be a possibility in this case.
Cheers,
Simon.
^ permalink raw reply
* Re: iptables bug
From: Patrick McHardy @ 2005-06-20 23:39 UTC (permalink / raw)
To: J.A. Magallon
Cc: Andrew Morton, netdev, Netfilter Development Mailinglist,
linux-kernel
In-Reply-To: <20050620153445.5daaed4e.akpm@osdl.org>
Andrew Morton wrote:
> "J.A. Magallon" <jamagallon@able.es> wrote:
>
>>Are there any known problems with iptables ?
No known problems.
>>I see strange things.
>>When I use bittorrent (azureus or bittorrent-gui), at the same time as
>>iptables (for nat and internet access for my ibook), when I stop a download
>>or exit from one of this apps my external network goes down.
>>I have tried the same without iptables loaded and it works fine.
What exactly do you mean with "network goes down"? Can you find out
where the packets disappear? Do they silently disappear, or do you get
an error code from sendmsg? What about received packets?
Regards
Patrick
^ permalink raw reply
* Re: [patch 02/15] ppp_mppe: add PPP MPPE encryption module
From: Jeff Garzik @ 2005-06-20 22:45 UTC (permalink / raw)
To: akpm-3NddpPZAyC0
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, netdev-u79uwXL29TY76Z2rM5mHXA,
Matt_Domsch-8PEkshWhKlo, Brice.Goglin-vYW+cPY1g1pg9hUCZPvPmw,
james.cameron-VXdhtT5mjnY,
pptpclient-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <200506202231.j5KMVpfS024640-bipKiLWnuIsyyg0EjBt7GtHuzzzSOjJt@public.gmane.org>
akpm-3NddpPZAyC0@public.gmane.org wrote:
> From: Matt Domsch <Matt_Domsch-8PEkshWhKlo@public.gmane.org>
>
> The patch below implements the Microsoft Point-to-Point Encryption method
> as a PPP compressor/decompressor. This is necessary for Linux clients and
> servers to interoperate with Microsoft Point-to-Point Tunneling Protocol
> (PPTP) servers (either Microsoft PPTP servers or the poptop project) which
> use MPPE to encrypt data when creating a VPN.
>
> This patch differs from the kernel_ppp_mppe DKMS pacakge at
> pptpclient.sourceforge.net by utilizing the kernel crypto routines rather
> than providing its own SHA1 and arcfour implementations.
>
> Minor changes to ppp_generic.c try to prevent a link from disabling
> compression (in our case, the encryption) after it has started using
> compression (encryption).
>
> Feedback to <pptpclient-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> please.
>
> Signed-off-by: Matt Domsch <Matt_Domsch-8PEkshWhKlo@public.gmane.org>
> Cc: James Cameron <james.cameron-VXdhtT5mjnY@public.gmane.org>
> Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> Signed-off-by: Brice Goglin <Brice.Goglin-vYW+cPY1g1pg9hUCZPvPmw@public.gmane.org>
> Signed-off-by: Andrew Morton <akpm-3NddpPZAyC0@public.gmane.org>
I'll review this, but ppp stuff really needs to go Paul MacKerras...
Jeff
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
^ permalink raw reply
* iptables bug (was: Re: 2.6.12-mm1)
From: Andrew Morton @ 2005-06-20 22:34 UTC (permalink / raw)
To: J.A. Magallon; +Cc: linux-kernel, netdev
In-Reply-To: <1119305756l.1344l.0l@werewolf.able.es>
"J.A. Magallon" <jamagallon@able.es> wrote:
>
>
> On 06.20, Andrew Morton wrote:
> >
> > ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.12/2.6.12-mm1/
> >
> >
> > - Someone broke /proc/device-tree on ppc64. It's being looked into.
> >
> > - Nothing particularly special here - various fixes and updates.
> >
>
> Are there any known problems with iptables ?
Let's cc the appropriate list and find out ;)
> I see strange things.
> When I use bittorrent (azureus or bittorrent-gui), at the same time as
> iptables (for nat and internet access for my ibook), when I stop a download
> or exit from one of this apps my external network goes down.
> I have tried the same without iptables loaded and it works fine.
>
> If someone has any idea about this, I could give more details.
>
> Kernel: every -mm since time ago.
> External net: 1Mb cable through 3c59x, dhcp
> Internal net: e1000
> Iptables setup:
> # Generated by iptables-save v1.2.9 on Thu Mar 3 23:41:02 2005
> *nat
> :PREROUTING ACCEPT [2:156]
> :POSTROUTING ACCEPT [0:0]
> :OUTPUT ACCEPT [0:0]
> [0:0] -A POSTROUTING -o eth0 -j MASQUERADE
> COMMIT
> # Completed on Thu Mar 3 23:41:02 2005
> # Generated by iptables-save v1.2.9 on Thu Mar 3 23:41:02 2005
> *filter
> :INPUT ACCEPT [6:468]
> :FORWARD DROP [0:0]
> :OUTPUT ACCEPT [0:0]
> [0:0] -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
> [0:0] -A FORWARD -i eth1 -o eth0 -j ACCEPT
> [0:0] -A FORWARD -i eth0 -o eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT
> [0:0] -A FORWARD -i eth2 -o eth0 -j ACCEPT
> [0:0] -A FORWARD -i eth0 -o eth3 -m state --state RELATED,ESTABLISHED -j ACCEPT
> [0:0] -A FORWARD -i eth3 -o eth0 -j ACCEPT
> COMMIT
> # Completed on Thu Mar 3 23:41:02 2005
>
> eth's:
> alias eth0 3c59x
> alias eth1 e1000
> alias eth2 ne2k-pci
> alias eth3 eth1394
>
> eth2 and eth3 are currently down, not even the module is loaded.
>
> Any idea ?
>
> --
> J.A. Magallon <jamagallon()able!es> \ Software is like sex:
> werewolf!able!es \ It's better when it's free
> Mandriva Linux release 2006.0 (Cooker) for i586
> Linux 2.6.12-jam1 (gcc 4.0.1 (4.0.1-0.2mdk for Mandriva Linux release 2006.0))
>
^ permalink raw reply
* [patch 02/15] ppp_mppe: add PPP MPPE encryption module
From: akpm-3NddpPZAyC0 @ 2005-06-20 22:32 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: jgarzik-e+AXbWqSrlAAvxtiuMwx3w, netdev-u79uwXL29TY76Z2rM5mHXA,
akpm-3NddpPZAyC0, Matt_Domsch-8PEkshWhKlo,
Brice.Goglin-vYW+cPY1g1pg9hUCZPvPmw, james.cameron-VXdhtT5mjnY,
pptpclient-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
From: Matt Domsch <Matt_Domsch-8PEkshWhKlo@public.gmane.org>
The patch below implements the Microsoft Point-to-Point Encryption method
as a PPP compressor/decompressor. This is necessary for Linux clients and
servers to interoperate with Microsoft Point-to-Point Tunneling Protocol
(PPTP) servers (either Microsoft PPTP servers or the poptop project) which
use MPPE to encrypt data when creating a VPN.
This patch differs from the kernel_ppp_mppe DKMS pacakge at
pptpclient.sourceforge.net by utilizing the kernel crypto routines rather
than providing its own SHA1 and arcfour implementations.
Minor changes to ppp_generic.c try to prevent a link from disabling
compression (in our case, the encryption) after it has started using
compression (encryption).
Feedback to <pptpclient-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> please.
Signed-off-by: Matt Domsch <Matt_Domsch-8PEkshWhKlo@public.gmane.org>
Cc: James Cameron <james.cameron-VXdhtT5mjnY@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Signed-off-by: Brice Goglin <Brice.Goglin-vYW+cPY1g1pg9hUCZPvPmw@public.gmane.org>
Signed-off-by: Andrew Morton <akpm-3NddpPZAyC0@public.gmane.org>
---
drivers/net/Kconfig | 13
drivers/net/Makefile | 1
drivers/net/ppp_generic.c | 79 +++--
drivers/net/ppp_mppe.c | 724 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/ppp_mppe.h | 87 +++++
include/linux/ppp-comp.h | 14
6 files changed, 895 insertions(+), 23 deletions(-)
diff -puN drivers/net/Kconfig~ppp_mppe-add-ppp-mppe-encryption-module drivers/net/Kconfig
--- 25/drivers/net/Kconfig~ppp_mppe-add-ppp-mppe-encryption-module Mon Jun 20 15:30:46 2005
+++ 25-akpm/drivers/net/Kconfig Mon Jun 20 15:30:52 2005
@@ -2437,6 +2437,19 @@ config PPP_BSDCOMP
module; it is called bsd_comp and will show up in the directory
modules once you have said "make modules". If unsure, say N.
+config PPP_MPPE
+ tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
+ depends on PPP && EXPERIMENTAL
+ select CRYPTO
+ select CRYPTO_SHA1
+ select CRYPTO_ARC4
+ ---help---
+ Support for the MPPE Encryption protocol, as employed by the
+ Microsoft Point-to-Point Tunneling Protocol.
+
+ See http://pptpclient.sourceforge.net/ for information on
+ configuring PPTP clients and servers to utilize this method.
+
config PPPOE
tristate "PPP over Ethernet (EXPERIMENTAL)"
depends on EXPERIMENTAL && PPP
diff -puN drivers/net/Makefile~ppp_mppe-add-ppp-mppe-encryption-module drivers/net/Makefile
--- 25/drivers/net/Makefile~ppp_mppe-add-ppp-mppe-encryption-module Mon Jun 20 15:30:46 2005
+++ 25-akpm/drivers/net/Makefile Mon Jun 20 15:30:46 2005
@@ -106,6 +106,7 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
+obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
obj-$(CONFIG_SLIP) += slip.o
diff -puN drivers/net/ppp_generic.c~ppp_mppe-add-ppp-mppe-encryption-module drivers/net/ppp_generic.c
--- 25/drivers/net/ppp_generic.c~ppp_mppe-add-ppp-mppe-encryption-module Mon Jun 20 15:30:46 2005
+++ 25-akpm/drivers/net/ppp_generic.c Mon Jun 20 15:30:46 2005
@@ -1027,6 +1027,53 @@ ppp_xmit_process(struct ppp *ppp)
ppp_xmit_unlock(ppp);
}
+static inline struct sk_buff *
+pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
+{
+ struct sk_buff *new_skb;
+ int len;
+ int new_skb_size = ppp->dev->mtu + ppp->xcomp->comp_skb_extra_space + ppp->dev->hard_header_len;
+ int compressor_skb_size = ppp->dev->mtu + ppp->xcomp->comp_skb_extra_space + PPP_HDRLEN;
+ new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
+ if (!new_skb) {
+ if (net_ratelimit())
+ printk(KERN_ERR "PPP: no memory (comp pkt)\n");
+ return NULL;
+ }
+ if (ppp->dev->hard_header_len > PPP_HDRLEN)
+ skb_reserve(new_skb,
+ ppp->dev->hard_header_len - PPP_HDRLEN);
+
+ /* compressor still expects A/C bytes in hdr */
+ len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
+ new_skb->data, skb->len + 2,
+ compressor_skb_size);
+ if (len > 0 && (ppp->flags & SC_CCP_UP)) {
+ kfree_skb(skb);
+ skb = new_skb;
+ skb_put(skb, len);
+ skb_pull(skb, 2); /* pull off A/C bytes */
+ } else if (len == 0) {
+ /* didn't compress, or CCP not up yet */
+ kfree_skb(new_skb);
+ new_skb = skb;
+ } else {
+ /*
+ * (len < 0)
+ * MPPE requires that we do not send unencrypted
+ * frames. The compressor will return -1 if we
+ * should drop the frame. We cannot simply test
+ * the compress_proto because MPPE and MPPC share
+ * the same number.
+ */
+ if (net_ratelimit())
+ printk(KERN_ERR "ppp: compressor dropped pkt\n");
+ kfree_skb(new_skb);
+ new_skb = NULL;
+ }
+ return new_skb;
+}
+
/*
* Compress and send a frame.
* The caller should have locked the xmit path,
@@ -1113,29 +1160,14 @@ ppp_send_frame(struct ppp *ppp, struct s
/* try to do packet compression */
if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
&& proto != PPP_LCP && proto != PPP_CCP) {
- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
- GFP_ATOMIC);
- if (new_skb == 0) {
- printk(KERN_ERR "PPP: no memory (comp pkt)\n");
+ if (!(ppp->flags & SC_CCP_UP) && ppp->xcomp->must_compress) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
goto drop;
}
- if (ppp->dev->hard_header_len > PPP_HDRLEN)
- skb_reserve(new_skb,
- ppp->dev->hard_header_len - PPP_HDRLEN);
-
- /* compressor still expects A/C bytes in hdr */
- len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
- new_skb->data, skb->len + 2,
- ppp->dev->mtu + PPP_HDRLEN);
- if (len > 0 && (ppp->flags & SC_CCP_UP)) {
- kfree_skb(skb);
- skb = new_skb;
- skb_put(skb, len);
- skb_pull(skb, 2); /* pull off A/C bytes */
- } else {
- /* didn't compress, or CCP not up yet */
- kfree_skb(new_skb);
- }
+ skb = pad_compress_skb(ppp, skb);
+ if (!skb)
+ goto drop;
}
/*
@@ -1155,7 +1187,8 @@ ppp_send_frame(struct ppp *ppp, struct s
return;
drop:
- kfree_skb(skb);
+ if (skb)
+ kfree_skb(skb);
++ppp->stats.tx_errors;
}
@@ -1683,7 +1716,7 @@ ppp_decompress_frame(struct ppp *ppp, st
goto err;
if (proto == PPP_COMP) {
- ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
+ ns = dev_alloc_skb(ppp->mru + ppp->rcomp->decomp_skb_extra_space + PPP_HDRLEN);
if (ns == 0) {
printk(KERN_ERR "ppp_decompress_frame: no memory\n");
goto err;
diff -puN /dev/null drivers/net/ppp_mppe.c
--- /dev/null Thu Apr 11 07:25:15 2002
+++ 25-akpm/drivers/net/ppp_mppe.c Mon Jun 20 15:30:46 2005
@@ -0,0 +1,724 @@
+/*
+ * ppp_mppe_compress.c - interface MPPE to the PPP code.
+ * This version is for use with Linux kernel 2.2.19+, 2.4.18+ and 2.6.2+.
+ *
+ * By Frank Cusack <frank-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>.
+ * Copyright (c) 2002,2003,2004 Google, Inc.
+ * All rights reserved.
+ *
+ * License:
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation is hereby granted, provided that the above copyright
+ * notice appears in all copies. This software is provided without any
+ * warranty, express or implied.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Changelog:
+ * 06/18/04 - Matt Domsch <Matt_Domsch-8PEkshWhKlo@public.gmane.org>, Oleg Makarenko <mole-aTJdtAV7WjCHXe+LvDLADg@public.gmane.org>
+ * Use Linux kernel 2.6 arc4 and sha1 routines rather than
+ * providing our own.
+ * 2/15/04 - TS: added #include <version.h> and testing for Kernel
+ * version before using
+ * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
+ * deprecated in 2.6
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/ppp_defs.h>
+#include <linux/ppp-comp.h>
+#include <asm/scatterlist.h>
+
+#include "ppp_mppe.h"
+
+MODULE_AUTHOR("Frank Cusack <frank-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
+MODULE_VERSION("1.0.2");
+
+static void
+setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
+{
+ sg[0].page = virt_to_page(address);
+ sg[0].offset = offset_in_page(address);
+ sg[0].length = length;
+}
+
+#define SHA1_PAD_SIZE 40
+
+/*
+ * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module
+ * static data area. That means sha_pad needs to be kmalloc'd.
+ */
+
+struct sha_pad {
+ unsigned char sha_pad1[SHA1_PAD_SIZE];
+ unsigned char sha_pad2[SHA1_PAD_SIZE];
+};
+static struct sha_pad *sha_pad;
+
+static inline void sha_pad_init(struct sha_pad *shapad)
+{
+ memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1));
+ memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2));
+}
+
+/*
+ * State for an MPPE (de)compressor.
+ */
+struct ppp_mppe_state {
+ struct crypto_tfm *arc4;
+ struct crypto_tfm *sha1;
+ unsigned char *sha1_digest;
+ unsigned char master_key[MPPE_MAX_KEY_LEN];
+ unsigned char session_key[MPPE_MAX_KEY_LEN];
+ unsigned keylen; /* key length in bytes */
+ /* NB: 128-bit == 16, 40-bit == 8! */
+ /* If we want to support 56-bit, */
+ /* the unit has to change to bits */
+ unsigned char bits; /* MPPE control bits */
+ unsigned ccount; /* 12-bit coherency count (seqno) */
+ unsigned stateful; /* stateful mode flag */
+ int discard; /* stateful mode packet loss flag */
+ int sanity_errors; /* take down LCP if too many */
+ int unit;
+ int debug;
+ struct compstat stats;
+};
+
+/* struct ppp_mppe_state.bits definitions */
+#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
+#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
+#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
+#define MPPE_BIT_D 0x10 /* This is an encrypted frame */
+
+#define MPPE_BIT_FLUSHED MPPE_BIT_A
+#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
+
+#define MPPE_BITS(p) ((p)[4] & 0xf0)
+#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
+#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
+
+#define MPPE_OVHD 2 /* MPPE overhead/packet */
+#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
+
+/*
+ * Key Derivation, from RFC 3078, RFC 3079.
+ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
+ */
+static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
+{
+ struct scatterlist sg[4];
+
+ setup_sg(&sg[0], state->master_key, state->keylen);
+ setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
+ setup_sg(&sg[2], state->session_key, state->keylen);
+ setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
+
+ crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
+
+ memcpy(InterimKey, state->sha1_digest, state->keylen);
+}
+
+/*
+ * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
+ * Well, not what's written there, but rather what they meant.
+ */
+static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
+{
+ unsigned char InterimKey[MPPE_MAX_KEY_LEN];
+ struct scatterlist sg_in[1], sg_out[1];
+
+ get_new_key_from_sha(state, InterimKey);
+ if (!initial_key) {
+ crypto_cipher_setkey(state->arc4, InterimKey, state->keylen);
+ setup_sg(sg_in, InterimKey, state->keylen);
+ setup_sg(sg_out, state->session_key, state->keylen);
+ if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in,
+ state->keylen) != 0) {
+ printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
+ }
+ } else {
+ memcpy(state->session_key, InterimKey, state->keylen);
+ }
+ if (state->keylen == 8) {
+ /* See RFC 3078 */
+ state->session_key[0] = 0xd1;
+ state->session_key[1] = 0x26;
+ state->session_key[2] = 0x9e;
+ }
+ crypto_cipher_setkey(state->arc4, state->session_key, state->keylen);
+}
+
+/*
+ * Allocate space for a (de)compressor.
+ */
+static void *mppe_alloc(unsigned char *options, int optlen)
+{
+ struct ppp_mppe_state *state;
+ unsigned int digestsize;
+
+ if (optlen != CILEN_MPPE + sizeof(state->master_key)
+ || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+ goto out;
+
+ state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+ if (state == NULL)
+ goto out;
+
+ memset(state, 0, sizeof(*state));
+
+ state->arc4 = crypto_alloc_tfm("arc4", 0);
+ if (!state->arc4)
+ goto out_free;
+
+ state->sha1 = crypto_alloc_tfm("sha1", 0);
+ if (!state->sha1)
+ goto out_free;
+
+ digestsize = crypto_tfm_alg_digestsize(state->sha1);
+ if (digestsize < MPPE_MAX_KEY_LEN)
+ goto out_free;
+
+ state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
+ if (!state->sha1_digest)
+ goto out_free;
+
+ /* Save keys. */
+ memcpy(state->master_key, &options[CILEN_MPPE],
+ sizeof(state->master_key));
+ memcpy(state->session_key, state->master_key,
+ sizeof(state->master_key));
+
+ /*
+ * We defer initial key generation until mppe_init(), as mppe_alloc()
+ * is called frequently during negotiation.
+ */
+
+ return (void *)state;
+
+ out_free:
+ if (state->sha1_digest)
+ kfree(state->sha1_digest);
+ if (state->sha1)
+ crypto_free_tfm(state->sha1);
+ if (state->arc4)
+ crypto_free_tfm(state->arc4);
+ kfree(state);
+ out:
+ return NULL;
+}
+
+/*
+ * Deallocate space for a (de)compressor.
+ */
+static void mppe_free(void *arg)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ if (state) {
+ if (state->sha1_digest)
+ kfree(state->sha1_digest);
+ if (state->sha1)
+ crypto_free_tfm(state->sha1);
+ if (state->arc4)
+ crypto_free_tfm(state->arc4);
+ kfree(state);
+ }
+}
+
+/*
+ * Initialize (de)compressor state.
+ */
+static int
+mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
+ const char *debugstr)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ unsigned char mppe_opts;
+
+ if (optlen != CILEN_MPPE
+ || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+ return 0;
+
+ MPPE_CI_TO_OPTS(&options[2], mppe_opts);
+ if (mppe_opts & MPPE_OPT_128)
+ state->keylen = 16;
+ else if (mppe_opts & MPPE_OPT_40)
+ state->keylen = 8;
+ else {
+ printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
+ unit);
+ return 0;
+ }
+ if (mppe_opts & MPPE_OPT_STATEFUL)
+ state->stateful = 1;
+
+ /* Generate the initial session key. */
+ mppe_rekey(state, 1);
+
+ if (debug) {
+ int i;
+ char mkey[sizeof(state->master_key) * 2 + 1];
+ char skey[sizeof(state->session_key) * 2 + 1];
+
+ printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
+ debugstr, unit, (state->keylen == 16) ? 128 : 40,
+ (state->stateful) ? "stateful" : "stateless");
+
+ for (i = 0; i < sizeof(state->master_key); i++)
+ sprintf(mkey + i * 2, "%02x", state->master_key[i]);
+ for (i = 0; i < sizeof(state->session_key); i++)
+ sprintf(skey + i * 2, "%02x", state->session_key[i]);
+ printk(KERN_DEBUG
+ "%s[%d]: keys: master: %s initial session: %s\n",
+ debugstr, unit, mkey, skey);
+ }
+
+ /*
+ * Initialize the coherency count. The initial value is not specified
+ * in RFC 3078, but we can make a reasonable assumption that it will
+ * start at 0. Setting it to the max here makes the comp/decomp code
+ * do the right thing (determined through experiment).
+ */
+ state->ccount = MPPE_CCOUNT_SPACE - 1;
+
+ /*
+ * Note that even though we have initialized the key table, we don't
+ * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
+ */
+ state->bits = MPPE_BIT_ENCRYPTED;
+
+ state->unit = unit;
+ state->debug = debug;
+
+ return 1;
+}
+
+static int
+mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
+ int hdrlen, int debug)
+{
+ /* ARGSUSED */
+ return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
+}
+
+/*
+ * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
+ * tell the compressor to rekey. Note that we MUST NOT rekey for
+ * every CCP Reset-Request; we only rekey on the next xmit packet.
+ * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
+ * So, rekeying for every CCP Reset-Request is broken as the peer will not
+ * know how many times we've rekeyed. (If we rekey and THEN get another
+ * CCP Reset-Request, we must rekey again.)
+ */
+static void mppe_comp_reset(void *arg)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ state->bits |= MPPE_BIT_FLUSHED;
+}
+
+/*
+ * Compress (encrypt) a packet.
+ * It's strange to call this a compressor, since the output is always
+ * MPPE_OVHD + 2 bytes larger than the input.
+ */
+static int
+mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
+ int isize, int osize)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ int proto;
+ struct scatterlist sg_in[1], sg_out[1];
+
+ /*
+ * Check that the protocol is in the range we handle.
+ */
+ proto = PPP_PROTOCOL(ibuf);
+ if (proto < 0x0021 || proto > 0x00fa)
+ return 0;
+
+ /* Make sure we have enough room to generate an encrypted packet. */
+ if (osize < isize + MPPE_OVHD + 2) {
+ /* Drop the packet if we should encrypt it, but can't. */
+ printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
+ "(have: %d need: %d)\n", state->unit,
+ osize, osize + MPPE_OVHD + 2);
+ return -1;
+ }
+
+ osize = isize + MPPE_OVHD + 2;
+
+ /*
+ * Copy over the PPP header and set control bits.
+ */
+ obuf[0] = PPP_ADDRESS(ibuf);
+ obuf[1] = PPP_CONTROL(ibuf);
+ obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */
+ obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */
+ obuf += PPP_HDRLEN;
+
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
+ state->ccount);
+ obuf[0] = state->ccount >> 8;
+ obuf[1] = state->ccount & 0xff;
+
+ if (!state->stateful || /* stateless mode */
+ ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
+ (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
+ /* We must rekey */
+ if (state->debug && state->stateful)
+ printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
+ state->unit);
+ mppe_rekey(state, 0);
+ state->bits |= MPPE_BIT_FLUSHED;
+ }
+ obuf[0] |= state->bits;
+ state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
+
+ obuf += MPPE_OVHD;
+ ibuf += 2; /* skip to proto field */
+ isize -= 2;
+
+ /* Encrypt packet */
+ setup_sg(sg_in, ibuf, isize);
+ setup_sg(sg_out, obuf, osize);
+ if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
+ return -1;
+ }
+
+ state->stats.unc_bytes += isize;
+ state->stats.unc_packets++;
+ state->stats.comp_bytes += osize;
+ state->stats.comp_packets++;
+
+ return osize;
+}
+
+/*
+ * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
+ * to look bad ... and the longer the link is up the worse it will get.
+ */
+static void mppe_comp_stats(void *arg, struct compstat *stats)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ *stats = state->stats;
+}
+
+static int
+mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
+ int hdrlen, int mru, int debug)
+{
+ /* ARGSUSED */
+ return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
+}
+
+/*
+ * We received a CCP Reset-Ack. Just ignore it.
+ */
+static void mppe_decomp_reset(void *arg)
+{
+ /* ARGSUSED */
+ return;
+}
+
+/*
+ * Decompress (decrypt) an MPPE packet.
+ */
+static int
+mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
+ int osize)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+ unsigned ccount;
+ int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
+ int sanity = 0;
+ struct scatterlist sg_in[1], sg_out[1];
+
+ if (isize <= PPP_HDRLEN + MPPE_OVHD) {
+ if (state->debug)
+ printk(KERN_DEBUG
+ "mppe_decompress[%d]: short pkt (%d)\n",
+ state->unit, isize);
+ return DECOMP_ERROR;
+ }
+
+ /*
+ * Make sure we have enough room to decrypt the packet.
+ * Note that for our test we only subtract 1 byte whereas in
+ * mppe_compress() we added 2 bytes (+MPPE_OVHD);
+ * this is to account for possible PFC.
+ */
+ if (osize < isize - MPPE_OVHD - 1) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
+ "(have: %d need: %d)\n", state->unit,
+ osize, isize - MPPE_OVHD - 1);
+ return DECOMP_ERROR;
+ }
+ osize = isize - MPPE_OVHD - 2; /* assume no PFC */
+
+ ccount = MPPE_CCOUNT(ibuf);
+ if (state->debug >= 7)
+ printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
+ state->unit, ccount);
+
+ /* sanity checks -- terminate with extreme prejudice */
+ if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
+ printk(KERN_DEBUG
+ "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
+ state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+ if (!state->stateful && !flushed) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
+ "stateless mode!\n", state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+ if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
+ "flag packet!\n", state->unit);
+ state->sanity_errors += 100;
+ sanity = 1;
+ }
+
+ if (sanity) {
+ if (state->sanity_errors < SANITY_MAX)
+ return DECOMP_ERROR;
+ else
+ /*
+ * Take LCP down if the peer is sending too many bogons.
+ * We don't want to do this for a single or just a few
+ * instances since it could just be due to packet corruption.
+ */
+ return DECOMP_FATALERROR;
+ }
+
+ /*
+ * Check the coherency count.
+ */
+
+ if (!state->stateful) {
+ /* RFC 3078, sec 8.1. Rekey for every packet. */
+ while (state->ccount != ccount) {
+ mppe_rekey(state, 0);
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ }
+ } else {
+ /* RFC 3078, sec 8.2. */
+ if (!state->discard) {
+ /* normal state */
+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+ if (ccount != state->ccount) {
+ /*
+ * (ccount > state->ccount)
+ * Packet loss detected, enter the discard state.
+ * Signal the peer to rekey (by sending a CCP Reset-Request).
+ */
+ state->discard = 1;
+ return DECOMP_ERROR;
+ }
+ } else {
+ /* discard state */
+ if (!flushed) {
+ /* ccp.c will be silent (no additional CCP Reset-Requests). */
+ return DECOMP_ERROR;
+ } else {
+ /* Rekey for every missed "flag" packet. */
+ while ((ccount & ~0xff) !=
+ (state->ccount & ~0xff)) {
+ mppe_rekey(state, 0);
+ state->ccount =
+ (state->ccount +
+ 256) % MPPE_CCOUNT_SPACE;
+ }
+
+ /* reset */
+ state->discard = 0;
+ state->ccount = ccount;
+ /*
+ * Another problem with RFC 3078 here. It implies that the
+ * peer need not send a Reset-Ack packet. But RFC 1962
+ * requires it. Hopefully, M$ does send a Reset-Ack; even
+ * though it isn't required for MPPE synchronization, it is
+ * required to reset CCP state.
+ */
+ }
+ }
+ if (flushed)
+ mppe_rekey(state, 0);
+ }
+
+ /*
+ * Fill in the first part of the PPP header. The protocol field
+ * comes from the decrypted data.
+ */
+ obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
+ obuf[1] = PPP_CONTROL(ibuf); /* +1 */
+ obuf += 2;
+ ibuf += PPP_HDRLEN + MPPE_OVHD;
+ isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
+ /* net osize: isize-4 */
+
+ /*
+ * Decrypt the first byte in order to check if it is
+ * a compressed or uncompressed protocol field.
+ */
+ setup_sg(sg_in, ibuf, 1);
+ setup_sg(sg_out, obuf, 1);
+ if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
+ return DECOMP_ERROR;
+ }
+
+ /*
+ * Do PFC decompression.
+ * This would be nicer if we were given the actual sk_buff
+ * instead of a char *.
+ */
+ if ((obuf[0] & 0x01) != 0) {
+ obuf[1] = obuf[0];
+ obuf[0] = 0;
+ obuf++;
+ osize++;
+ }
+
+ /* And finally, decrypt the rest of the packet. */
+ setup_sg(sg_in, ibuf + 1, isize - 1);
+ setup_sg(sg_out, obuf + 1, osize - 1);
+ if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) {
+ printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
+ return DECOMP_ERROR;
+ }
+
+ state->stats.unc_bytes += osize;
+ state->stats.unc_packets++;
+ state->stats.comp_bytes += isize;
+ state->stats.comp_packets++;
+
+ /* good packet credit */
+ state->sanity_errors >>= 1;
+
+ return osize;
+}
+
+/*
+ * Incompressible data has arrived (this should never happen!).
+ * We should probably drop the link if the protocol is in the range
+ * of what should be encrypted. At the least, we should drop this
+ * packet. (How to do this?)
+ */
+static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
+{
+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+ if (state->debug &&
+ (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
+ printk(KERN_DEBUG
+ "mppe_incomp[%d]: incompressible (unencrypted) data! "
+ "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
+
+ state->stats.inc_bytes += icnt;
+ state->stats.inc_packets++;
+ state->stats.unc_bytes += icnt;
+ state->stats.unc_packets++;
+}
+
+/*************************************************************
+ * Module interface table
+ *************************************************************/
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+static struct compressor ppp_mppe = {
+ .compress_proto = CI_MPPE,
+ .comp_alloc = mppe_alloc,
+ .comp_free = mppe_free,
+ .comp_init = mppe_comp_init,
+ .comp_reset = mppe_comp_reset,
+ .compress = mppe_compress,
+ .comp_stat = mppe_comp_stats,
+ .decomp_alloc = mppe_alloc,
+ .decomp_free = mppe_free,
+ .decomp_init = mppe_decomp_init,
+ .decomp_reset = mppe_decomp_reset,
+ .decompress = mppe_decompress,
+ .incomp = mppe_incomp,
+ .decomp_stat = mppe_comp_stats,
+ .owner = THIS_MODULE,
+ .comp_skb_extra_space = MPPE_COMPRESS_PAD,
+ .decomp_skb_extra_space = MPPE_DECOMPRESS_PAD,
+ .must_compress = 1,
+};
+
+/*
+ * ppp_mppe_init()
+ *
+ * Prior to allowing load, try to load the arc4 and sha1 crypto
+ * libraries. The actual use will be allocated later, but
+ * this way the module will fail to insmod if they aren't available.
+ */
+
+static int __init ppp_mppe_init(void)
+{
+ int answer;
+ if (!(crypto_alg_available("arc4", 0) &&
+ crypto_alg_available("sha1", 0)))
+ return -ENODEV;
+
+ sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
+ if (!sha_pad)
+ return -ENOMEM;
+ sha_pad_init(sha_pad);
+
+ answer = ppp_register_compressor(&ppp_mppe);
+
+ if (answer == 0)
+ printk(KERN_INFO "PPP MPPE Compression module registered\n");
+ else
+ kfree(sha_pad);
+
+ return answer;
+}
+
+static void __exit ppp_mppe_cleanup(void)
+{
+ ppp_unregister_compressor(&ppp_mppe);
+ kfree(sha_pad);
+}
+
+module_init(ppp_mppe_init);
+module_exit(ppp_mppe_cleanup);
diff -puN /dev/null drivers/net/ppp_mppe.h
--- /dev/null Thu Apr 11 07:25:15 2002
+++ 25-akpm/drivers/net/ppp_mppe.h Mon Jun 20 15:30:46 2005
@@ -0,0 +1,87 @@
+#define MPPE_COMPRESS_PAD 8 /* MPPE growth per frame */
+#define MPPE_DECOMPRESS_PAD 128
+#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
+
+/* option bits for ccp_options.mppe */
+#define MPPE_OPT_40 0x01 /* 40 bit */
+#define MPPE_OPT_128 0x02 /* 128 bit */
+#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */
+/* unsupported opts */
+#define MPPE_OPT_56 0x08 /* 56 bit */
+#define MPPE_OPT_MPPC 0x10 /* MPPC compression */
+#define MPPE_OPT_D 0x20 /* Unknown */
+#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
+#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */
+
+/*
+ * This is not nice ... the alternative is a bitfield struct though.
+ * And unfortunately, we cannot share the same bits for the option
+ * names above since C and H are the same bit. We could do a u_int32
+ * but then we have to do a htonl() all the time and/or we still need
+ * to know which octet is which.
+ */
+#define MPPE_C_BIT 0x01 /* MPPC */
+#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */
+#define MPPE_L_BIT 0x20 /* 40-bit */
+#define MPPE_S_BIT 0x40 /* 128-bit */
+#define MPPE_M_BIT 0x80 /* 56-bit, not supported */
+#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */
+
+/* Does not include H bit; used for least significant octet only. */
+#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
+
+/* Build a CI from mppe opts (see RFC 3078) */
+#define MPPE_OPTS_TO_CI(opts, ci) \
+ do { \
+ u_char *ptr = ci; /* u_char[4] */ \
+ \
+ /* H bit */ \
+ if (opts & MPPE_OPT_STATEFUL) \
+ *ptr++ = 0x0; \
+ else \
+ *ptr++ = MPPE_H_BIT; \
+ *ptr++ = 0; \
+ *ptr++ = 0; \
+ \
+ /* S,L bits */ \
+ *ptr = 0; \
+ if (opts & MPPE_OPT_128) \
+ *ptr |= MPPE_S_BIT; \
+ if (opts & MPPE_OPT_40) \
+ *ptr |= MPPE_L_BIT; \
+ /* M,D,C bits not supported */ \
+ } while (/* CONSTCOND */ 0)
+
+/* The reverse of the above */
+#define MPPE_CI_TO_OPTS(ci, opts) \
+ do { \
+ u_char *ptr = ci; /* u_char[4] */ \
+ \
+ opts = 0; \
+ \
+ /* H bit */ \
+ if (!(ptr[0] & MPPE_H_BIT)) \
+ opts |= MPPE_OPT_STATEFUL; \
+ \
+ /* S,L bits */ \
+ if (ptr[3] & MPPE_S_BIT) \
+ opts |= MPPE_OPT_128; \
+ if (ptr[3] & MPPE_L_BIT) \
+ opts |= MPPE_OPT_40; \
+ \
+ /* M,D,C bits */ \
+ if (ptr[3] & MPPE_M_BIT) \
+ opts |= MPPE_OPT_56; \
+ if (ptr[3] & MPPE_D_BIT) \
+ opts |= MPPE_OPT_D; \
+ if (ptr[3] & MPPE_C_BIT) \
+ opts |= MPPE_OPT_MPPC; \
+ \
+ /* Other bits */ \
+ if (ptr[0] & ~MPPE_H_BIT) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ if (ptr[1] || ptr[2]) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ if (ptr[3] & ~MPPE_ALL_BITS) \
+ opts |= MPPE_OPT_UNKNOWN; \
+ } while (/* CONSTCOND */ 0)
diff -puN include/linux/ppp-comp.h~ppp_mppe-add-ppp-mppe-encryption-module include/linux/ppp-comp.h
--- 25/include/linux/ppp-comp.h~ppp_mppe-add-ppp-mppe-encryption-module Mon Jun 20 15:30:46 2005
+++ 25-akpm/include/linux/ppp-comp.h Mon Jun 20 15:30:46 2005
@@ -111,6 +111,13 @@ struct compressor {
/* Used in locking compressor modules */
struct module *owner;
+ /* Extra skb space needed by the compressor algorithm */
+ unsigned int comp_skb_extra_space;
+ /* Extra skb space needed by the decompressor algorithm */
+ unsigned int decomp_skb_extra_space;
+ /* if must_compress is set, but ppp->flags != SC_CCP_UP
+ * then drop the packet */
+ unsigned int must_compress;
};
/*
@@ -191,6 +198,13 @@ struct compressor {
#define DEFLATE_CHK_SEQUENCE 0
/*
+ * Definitions for MPPE.
+ */
+
+#define CI_MPPE 18 /* config option for MPPE */
+#define CILEN_MPPE 6 /* length of config option */
+
+/*
* Definitions for other, as yet unsupported, compression methods.
*/
_
-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
^ permalink raw reply
* Re: [PATCH net-drivers-2.6 0/9] ixgb: driver update
From: Ganesh Venkatesan @ 2005-06-20 21:29 UTC (permalink / raw)
To: Malli Chilakala, jgarzik@pobox.com, netdev
In-Reply-To: <20050620002244.GB16859@tuxdriver.com>
John:
Are you subscribed to netdev@vger.kernel.org?
ganesh.
On 6/19/05, John W. Linville <linville@tuxdriver.com> wrote:
> On Fri, Jun 17, 2005 at 04:54:36PM -0700, Malli Chilakala wrote:
> > ixgb: driver update
>
> > 1. Set RXDCTL:PTHRESH/HTHRESH to zero
> > 2. Fix unnecessary link state messages
> > 3. Use netdev_priv() instead of netdev->priv
> > 4. Fix Broadcast/Multicast packets received statistics
> > 5. Fix data output by ethtool -d
> > 6. Ethtool cleanup patch from Stephen Hemminger
> > 7. Remove unused functions, render some variable static instead of global
> > 8. Redefined buffer_info-dma to be dma_addr_t instead of uint64
> > 9. Driver version & white space fixes
>
> Hmmm...I only got parts 1 & 2...anyone else missing parts?
>
> --
> John W. Linville
> linville@tuxdriver.com
>
>
^ permalink raw reply
* Re: [PATCH] ax25: endian-annotate ax25_type_trans()
From: David S. Miller @ 2005-06-20 20:26 UTC (permalink / raw)
To: ralf; +Cc: adobriyan, linux-hams, netdev, viro
In-Reply-To: <20050620103135.GC6633@linux-mips.org>
From: Ralf Baechle DL5RB <ralf@linux-mips.org>
Date: Mon, 20 Jun 2005 11:31:35 +0100
> Obviously correct, Dave would you apply this one?
Yep, I will.
^ permalink raw reply
* Re: [net-2.6.13 0/3] [IPSEC] Allow PMTU discovery to be turned off
From: David S. Miller @ 2005-06-20 20:24 UTC (permalink / raw)
To: herbert; +Cc: jmorris, kaber, yoshfuji, netdev
In-Reply-To: <20050613073353.GA21454@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Mon, 13 Jun 2005 17:33:53 +1000
> One of the problems that's been plaguing our IPsec stack is ICMP
> blackholes. ICMP blackholes are particularly bad for tunnels because
> the most common remediy -- MSS clamping has no effect when applied
> outside the tunnel. It is often impractical to apply it inside
> the tunnel since the point where the clamping is applied may be some
> way away from either IPsec endpoint.
>
> The best solution so far has been to disable PMTU discovery when a
> blackhole is detected. We already support that for IPIP/GRE tunnels.
> The following patchset adds support for a similar strategy to IPsec
> tunnels.
>
> It is by no means ideal but it's something that you need to survive
> on today's Internet.
All 3 patches applied, thanks Herbert.
One thing needs clarification in your description. When I first
read "blackhole is detected" I was under the wrong impression as
to _who_ does the detection. Your patches allow the administrator
to do this, whereas I thought you were going to add some code which
dynamically figured out the presence of ICMP black holes and would
thus set the bit.
^ permalink raw reply
* Re: netpoll and the bonding driver
From: Jeff Moyer @ 2005-06-20 15:01 UTC (permalink / raw)
To: John W. Linville; +Cc: Matt Mackall, netdev, linux-kernel
In-Reply-To: <20050620002118.GA16859@tuxdriver.com>
==> Regarding Re: netpoll and the bonding driver; "John W. Linville" <linville@tuxdriver.com> adds:
linville> On Sun, Jun 19, 2005 at 11:14:36AM -0700, Matt Mackall wrote:
>> On Fri, Jun 17, 2005 at 03:56:35PM -0400, Jeff Moyer wrote:
>> > I'm trying to implement a netpoll hook for the bonding driver.
>>
>> My first question would be: does this really make sense to do? Why not
>> just bind netpoll to one of the underlying devices?
linville> Depending on the bonding mode, this would be very unlikely to
linville> work. The other side of the link will still be expecting to talk
linville> to the bond rather than to an individual link.
Right, and for those drivers which register a netpoll_rx routine, they may
not get all of the packets destined for them.
-Jeff
^ permalink raw reply
* [patch] ipw2100: remove commented-out code
From: Pavel Machek @ 2005-06-20 11:33 UTC (permalink / raw)
To: Netdev list, Andrew Morton, Jeff Garzik, James P. Ketrenos
This removes up various code/defines that was just commented out
instead of being deleted.
--- clean-mm/drivers/net/wireless/ipw2100.c 2005-06-20 12:34:33.000000000 +0200
+++ linux-mm/drivers/net/wireless/ipw2100.c 2005-06-20 12:55:03.000000000 +0200
@@ -915,12 +907,10 @@
if (i == 10000)
return -EIO; /* TODO: better error value */
-//#if CONFIG_IPW2100_D0ENABLED
/* set D0 standby bit */
read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
write_register(priv->net_dev, IPW_REG_GP_CNTRL,
r | IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
-//#endif
return 0;
}
--- clean-mm/drivers/net/wireless/ipw2100.h 2005-06-20 12:34:33.000000000 +0200
+++ linux-mm/drivers/net/wireless/ipw2100.h 2005-06-20 12:55:10.000000000 +0200
@@ -320,7 +318,7 @@
u16 fragment_size;
} __attribute__ ((packed));
-// Host command data structure
+/* Host command data structure */
struct host_command {
u32 host_command; // COMMAND ID
u32 host_command1; // COMMAND ID
@@ -663,7 +656,7 @@
#define MSDU_TX_RATES 62
-// Rogue AP Detection
+/* Rogue AP Detection */
#define SET_STATION_STAT_BITS 64
#define CLEAR_STATIONS_STAT_BITS 65
#define LEAP_ROGUE_MODE 66 //TODO tbw replaced by CFG_LEAP_ROGUE_AP
@@ -673,25 +666,16 @@
-// system configuration bit mask:
-//#define IPW_CFG_ANTENNA_SETTING 0x03
-//#define IPW_CFG_ANTENNA_A 0x01
-//#define IPW_CFG_ANTENNA_B 0x02
+/* system configuration bit mask: */
#define IPW_CFG_MONITOR 0x00004
-//#define IPW_CFG_TX_STATUS_ENABLE 0x00008
#define IPW_CFG_PREAMBLE_AUTO 0x00010
#define IPW_CFG_IBSS_AUTO_START 0x00020
-//#define IPW_CFG_KERBEROS_ENABLE 0x00040
#define IPW_CFG_LOOPBACK 0x00100
-//#define IPW_CFG_WNMP_PING_PASS 0x00200
-//#define IPW_CFG_DEBUG_ENABLE 0x00400
#define IPW_CFG_ANSWER_BCSSID_PROBE 0x00800
-//#define IPW_CFG_BT_PRIORITY 0x01000
#define IPW_CFG_BT_SIDEBAND_SIGNAL 0x02000
#define IPW_CFG_802_1x_ENABLE 0x04000
#define IPW_CFG_BSS_MASK 0x08000
#define IPW_CFG_IBSS_MASK 0x10000
-//#define IPW_CFG_DYNAMIC_CW 0x10000
#define IPW_SCAN_NOASSOCIATE (1<<0)
#define IPW_SCAN_MIXED_CELL (1<<1)
@@ -840,7 +824,7 @@
} rx_data;
} __attribute__ ((packed));
-// Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved
+/* Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved */
#define TX_RATE_1_MBIT 0x0001
#define TX_RATE_2_MBIT 0x0002
#define TX_RATE_5_5_MBIT 0x0004
@@ -1120,7 +1104,6 @@
IPW_ORD_UCODE_VERSION, // Ucode Version
IPW_ORD_HW_RF_SWITCH_STATE = 214, // HW RF Kill Switch State
} ORDINALTABLE1;
-//ENDOF TABLE1
// ordinal table 2
// Variable length data:
--
teflon -- maybe it is a trademark, but it should not be.
^ permalink raw reply
* [patch] ipw2100: remove by-hand function entry/exit debugging
From: Pavel Machek @ 2005-06-20 11:29 UTC (permalink / raw)
To: Netdev list, Andrew Morton, Jeff Garzik, James P. Ketrenos
This removes debug prints from entry/exit of functions. Such level of
debugging should probably be done by gdb or similar.
Signed-off-by: Pavel Machek <pavel@suse.cz>
--- clean-mm/drivers/net/wireless/ipw2100.c 2005-06-20 12:34:33.000000000 +0200
+++ linux-mm/drivers/net/wireless/ipw2100.c 2005-06-20 12:55:03.000000000 +0200
@@ -1083,8 +1046,6 @@
{
struct ipw2100_ordinals *ord = &priv->ordinals;
- IPW_DEBUG_INFO("enter\n");
-
read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1,
&ord->table1_addr);
@@ -1095,10 +1056,6 @@
read_nic_dword(priv->net_dev, ord->table2_addr, &ord->table2_size);
ord->table2_size &= 0x0000FFFF;
-
- IPW_DEBUG_INFO("table 1 size: %d\n", ord->table1_size);
- IPW_DEBUG_INFO("table 2 size: %d\n", ord->table2_size);
- IPW_DEBUG_INFO("exit\n");
}
static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
@@ -1196,8 +1153,6 @@
int i;
u32 inta, inta_mask, gpio;
- IPW_DEBUG_INFO("enter\n");
-
if (priv->status & STATUS_RUNNING)
return 0;
@@ -1284,9 +1239,6 @@
/* The adapter has been reset; we are not associated */
priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -1596,8 +1548,6 @@
};
int err;
- IPW_DEBUG_INFO("enter\n");
-
IPW_DEBUG_SCAN("setting scan options\n");
cmd.host_command_parameters[0] = 0;
@@ -1641,8 +1591,6 @@
return 0;
}
- IPW_DEBUG_INFO("enter\n");
-
/* Not clearing here; doing so makes iwlist always return nothing...
*
* We should modify the table logic to use aging tables vs. clearing
@@ -1655,8 +1603,6 @@
if (err)
priv->status &= ~STATUS_SCANNING;
- IPW_DEBUG_INFO("exit\n");
-
return err;
}
@@ -3190,8 +3087,6 @@
ipw2100_enable_interrupts(priv);
spin_unlock_irqrestore(&priv->low_lock, flags);
-
- IPW_DEBUG_ISR("exit\n");
}
@@ -4149,43 +3460,32 @@
{
struct ipw2100_status_queue *q = &priv->status_queue;
- IPW_DEBUG_INFO("enter\n");
-
q->size = entries * sizeof(struct ipw2100_status);
q->drv = (struct ipw2100_status *)pci_alloc_consistent(
priv->pci_dev, q->size, &q->nic);
if (!q->drv) {
- IPW_DEBUG_WARNING(
+ printk(KERN_WARNING DRV_NAME ": "
"Can not allocate status queue.\n");
return -ENOMEM;
}
memset(q->drv, 0, q->size);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
static void status_queue_free(struct ipw2100_priv *priv)
{
- IPW_DEBUG_INFO("enter\n");
-
if (priv->status_queue.drv) {
pci_free_consistent(
priv->pci_dev, priv->status_queue.size,
priv->status_queue.drv, priv->status_queue.nic);
priv->status_queue.drv = NULL;
}
-
- IPW_DEBUG_INFO("exit\n");
}
static int bd_queue_allocate(struct ipw2100_priv *priv,
struct ipw2100_bd_queue *q, int entries)
{
- IPW_DEBUG_INFO("enter\n");
-
memset(q, 0, sizeof(struct ipw2100_bd_queue));
q->entries = entries;
@@ -4196,17 +3496,12 @@
return -ENOMEM;
}
memset(q->drv, 0, q->size);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
static void bd_queue_free(struct ipw2100_priv *priv,
struct ipw2100_bd_queue *q)
{
- IPW_DEBUG_INFO("enter\n");
-
if (!q)
return;
@@ -4215,24 +3510,18 @@
q->size, q->drv, q->nic);
q->drv = NULL;
}
-
- IPW_DEBUG_INFO("exit\n");
}
static void bd_queue_initialize(
struct ipw2100_priv *priv, struct ipw2100_bd_queue * q,
u32 base, u32 size, u32 r, u32 w)
{
- IPW_DEBUG_INFO("enter\n");
-
IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, q->nic);
write_register(priv->net_dev, base, q->nic);
write_register(priv->net_dev, size, q->entries);
write_register(priv->net_dev, r, q->oldest);
write_register(priv->net_dev, w, q->next);
-
- IPW_DEBUG_INFO("exit\n");
}
static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
@@ -4256,11 +3545,9 @@
void *v;
dma_addr_t p;
- IPW_DEBUG_INFO("enter\n");
-
err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
if (err) {
- IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
+ printk(KERN_ERR DRV_NAME ": %s: failed bd_queue_allocate\n",
priv->net_dev->name);
return err;
}
@@ -4312,8 +3599,6 @@
{
int i;
- IPW_DEBUG_INFO("enter\n");
-
/*
* reinitialize packet info lists
*/
@@ -4352,17 +3637,12 @@
IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE,
IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX);
-
- IPW_DEBUG_INFO("exit\n");
-
}
static void ipw2100_tx_free(struct ipw2100_priv *priv)
{
int i;
- IPW_DEBUG_INFO("enter\n");
-
bd_queue_free(priv, &priv->tx_queue);
if (!priv->tx_buffers)
@@ -4383,8 +3663,6 @@
kfree(priv->tx_buffers);
priv->tx_buffers = NULL;
-
- IPW_DEBUG_INFO("exit\n");
}
@@ -4393,8 +3671,6 @@
{
int i, j, err = -EINVAL;
- IPW_DEBUG_INFO("enter\n");
-
err = bd_queue_allocate(priv, &priv->rx_queue, RX_QUEUE_LENGTH);
if (err) {
IPW_DEBUG_INFO("failed bd_queue_allocate\n");
@@ -4416,11 +3692,8 @@
GFP_KERNEL);
if (!priv->rx_buffers) {
IPW_DEBUG_INFO("can't allocate rx packet buffer table\n");
-
bd_queue_free(priv, &priv->rx_queue);
-
status_queue_free(priv);
-
return -ENOMEM;
}
@@ -4461,8 +3734,6 @@
static void ipw2100_rx_initialize(struct ipw2100_priv *priv)
{
- IPW_DEBUG_INFO("enter\n");
-
priv->rx_queue.oldest = 0;
priv->rx_queue.available = priv->rx_queue.entries - 1;
priv->rx_queue.next = priv->rx_queue.entries - 1;
@@ -4479,16 +3750,12 @@
/* set up the status queue */
write_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_STATUS_BASE,
priv->status_queue.nic);
-
- IPW_DEBUG_INFO("exit\n");
}
static void ipw2100_rx_free(struct ipw2100_priv *priv)
{
int i;
- IPW_DEBUG_INFO("enter\n");
-
bd_queue_free(priv, &priv->rx_queue);
status_queue_free(priv);
@@ -4507,8 +3774,6 @@
kfree(priv->rx_buffers);
priv->rx_buffers = NULL;
-
- IPW_DEBUG_INFO("exit\n");
}
static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
@@ -4549,8 +3814,6 @@
IPW_DEBUG_HC("SET_MAC_ADDRESS\n");
- IPW_DEBUG_INFO("enter\n");
-
if (priv->config & CFG_CUSTOM_MAC) {
memcpy(cmd.host_command_parameters, priv->mac_addr,
ETH_ALEN);
@@ -4560,8 +3823,6 @@
ETH_ALEN);
err = ipw2100_hw_send_command(priv, &cmd);
-
- IPW_DEBUG_INFO("exit\n");
return err;
}
@@ -4948,8 +4168,6 @@
int err;
int len;
- IPW_DEBUG_HC("DISASSOCIATION_BSSID\n");
-
len = ETH_ALEN;
/* The Firmware currently ignores the BSSID and just disassociates from
* the currently associated AP -- but in the off chance that a future
@@ -5009,8 +4196,6 @@
};
int err;
- IPW_DEBUG_HC("SET_WPA_IE\n");
-
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
if (err)
@@ -5136,8 +4321,6 @@
cmd.host_command_parameters[0] = interval;
- IPW_DEBUG_INFO("enter\n");
-
if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
if (!batch_mode) {
err = ipw2100_disable_adapter(priv);
@@ -5153,9 +4336,6 @@
return err;
}
}
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -5515,8 +4695,6 @@
int batch_mode = 1;
u8 *bssid;
- IPW_DEBUG_INFO("enter\n");
-
err = ipw2100_disable_adapter(priv);
if (err)
return err;
@@ -5525,9 +4703,6 @@
err = ipw2100_set_channel(priv, priv->channel, batch_mode);
if (err)
return err;
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
#endif /* CONFIG_IPW2100_MONITOR */
@@ -5604,9 +4779,6 @@
if (err)
return err;
*/
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -5669,8 +4841,6 @@
struct list_head *element;
struct ipw2100_tx_packet *packet;
- IPW_DEBUG_INFO("enter\n");
-
spin_lock_irqsave(&priv->low_lock, flags);
if (priv->status & STATUS_ASSOCIATED)
@@ -5692,9 +4862,6 @@
INC_STAT(&priv->tx_free_stat);
}
spin_unlock_irqrestore(&priv->low_lock, flags);
-
- IPW_DEBUG_INFO("exit\n");
-
return 0;
}
@@ -6449,8 +5616,6 @@
int registered = 0;
u32 val;
- IPW_DEBUG_INFO("enter\n");
-
mem_start = pci_resource_start(pci_dev, 0);
mem_len = pci_resource_len(pci_dev, 0);
mem_flags = pci_resource_flags(pci_dev, 0);
@@ -6598,8 +5763,6 @@
ipw2100_start_scan(priv);
}
- IPW_DEBUG_INFO("exit\n");
-
priv->status |= STATUS_INITIALIZED;
up(&priv->action_sem);
@@ -6689,17 +5851,11 @@
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
-
- IPW_DEBUG_INFO("exit\n");
}
#ifdef CONFIG_PM
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
-#else
static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
-#endif
{
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
struct net_device *dev = priv->net_dev;
@@ -8288,8 +7444,6 @@
down(&priv->action_sem);
- IPW_DEBUG_WX("enter\n");
-
up(&priv->action_sem);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
--
teflon -- maybe it is a trademark, but it should not be.
^ permalink raw reply
* Re: [PATCH] ax25: endian-annotate ax25_type_trans()
From: Ralf Baechle DL5RB @ 2005-06-20 10:31 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: linux-hams, netdev, Al Viro
In-Reply-To: <200506200026.04525.adobriyan@gmail.com>
On Mon, Jun 20, 2005 at 12:26:04AM +0400, Alexey Dobriyan wrote:
> Subject: [PATCH] ax25: endian-annotate ax25_type_trans()
> Date: Mon, 20 Jun 2005 00:26:04 +0400
> Cc: linux-hams@vger.kernel.org, netdev@vger.kernel.org,
> Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
> Content-Type: text/plain;
> charset="us-ascii"
Obviously correct, Dave would you apply this one?
Ralf
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
>
> Index: linux-sparse/include/net/ax25.h
> ===================================================================
> --- linux-sparse.orig/include/net/ax25.h 2005-06-10 09:24:10.000000000 +0400
> +++ linux-sparse/include/net/ax25.h 2005-06-10 15:03:30.000000000 +0400
> @@ -220,7 +220,7 @@ static __inline__ void ax25_cb_put(ax25_
> }
> }
>
> -static inline unsigned short ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
> +static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
> {
> skb->dev = dev;
> skb->pkt_type = PACKET_HOST;
73 de DL5RB op Ralf
--
Loc. JN47BS / CQ 14 / ITU 28 / DOK A21
^ permalink raw reply
* Re: [PATCH net-drivers-2.6 0/9] ixgb: driver update
From: John W. Linville @ 2005-06-20 0:22 UTC (permalink / raw)
To: Malli Chilakala; +Cc: jgarzik@pobox.com, netdev
In-Reply-To: <Pine.LNX.4.61.0506131232570.24260@anoushka.jf.intel.com>
On Fri, Jun 17, 2005 at 04:54:36PM -0700, Malli Chilakala wrote:
> ixgb: driver update
> 1. Set RXDCTL:PTHRESH/HTHRESH to zero
> 2. Fix unnecessary link state messages
> 3. Use netdev_priv() instead of netdev->priv
> 4. Fix Broadcast/Multicast packets received statistics
> 5. Fix data output by ethtool -d
> 6. Ethtool cleanup patch from Stephen Hemminger
> 7. Remove unused functions, render some variable static instead of global
> 8. Redefined buffer_info-dma to be dma_addr_t instead of uint64
> 9. Driver version & white space fixes
Hmmm...I only got parts 1 & 2...anyone else missing parts?
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply
* Re: netpoll and the bonding driver
From: John W. Linville @ 2005-06-20 0:21 UTC (permalink / raw)
To: Matt Mackall; +Cc: Jeff Moyer, netdev, linux-kernel
In-Reply-To: <20050619181436.GX27572@waste.org>
On Sun, Jun 19, 2005 at 11:14:36AM -0700, Matt Mackall wrote:
> On Fri, Jun 17, 2005 at 03:56:35PM -0400, Jeff Moyer wrote:
> > I'm trying to implement a netpoll hook for the bonding driver.
>
> My first question would be: does this really make sense to do? Why not
> just bind netpoll to one of the underlying devices?
Depending on the bonding mode, this would be very unlikely to work.
The other side of the link will still be expecting to talk to the
bond rather than to an individual link.
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox