* [PATCH] WAN: fix Cisco HDLC handshaking.
@ 2009-10-09 16:16 Krzysztof Halasa
2009-10-13 10:18 ` David Miller
0 siblings, 1 reply; 2+ messages in thread
From: Krzysztof Halasa @ 2009-10-09 16:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev
WAN: fix Cisco HDLC handshaking.
Cisco HDLC uses keepalive packets and sequence numbers to determine link
state. In rare cases both ends could transmit keepalive packets at the same
time, causing the received sequence numbers to be treated as incorrect.
Now we accept our current sequence number as well as the previous one.
Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index cf5fd17..f1bff98 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -58,8 +58,7 @@ struct cisco_state {
spinlock_t lock;
unsigned long last_poll;
int up;
- int request_sent;
- u32 txseq; /* TX sequence number */
+ u32 txseq; /* TX sequence number, 0 = none */
u32 rxseq; /* RX sequence number */
};
@@ -163,6 +162,7 @@ static int cisco_rx(struct sk_buff *skb)
struct cisco_packet *cisco_data;
struct in_device *in_dev;
__be32 addr, mask;
+ u32 ack;
if (skb->len < sizeof(struct hdlc_header))
goto rx_error;
@@ -223,8 +223,10 @@ static int cisco_rx(struct sk_buff *skb)
case CISCO_KEEPALIVE_REQ:
spin_lock(&st->lock);
st->rxseq = ntohl(cisco_data->par1);
- if (st->request_sent &&
- ntohl(cisco_data->par2) == st->txseq) {
+ ack = ntohl(cisco_data->par2);
+ if (ack && (ack == st->txseq ||
+ /* our current REQ may be in transit */
+ ack == st->txseq - 1)) {
st->last_poll = jiffies;
if (!st->up) {
u32 sec, min, hrs, days;
@@ -275,7 +277,6 @@ static void cisco_timer(unsigned long arg)
cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq),
htonl(st->rxseq));
- st->request_sent = 1;
spin_unlock(&st->lock);
st->timer.expires = jiffies + st->settings.interval * HZ;
@@ -293,9 +294,7 @@ static void cisco_start(struct net_device *dev)
unsigned long flags;
spin_lock_irqsave(&st->lock, flags);
- st->up = 0;
- st->request_sent = 0;
- st->txseq = st->rxseq = 0;
+ st->up = st->txseq = st->rxseq = 0;
spin_unlock_irqrestore(&st->lock, flags);
init_timer(&st->timer);
@@ -317,8 +316,7 @@ static void cisco_stop(struct net_device *dev)
spin_lock_irqsave(&st->lock, flags);
netif_dormant_on(dev);
- st->up = 0;
- st->request_sent = 0;
+ st->up = st->txseq = 0;
spin_unlock_irqrestore(&st->lock, flags);
}
--
Krzysztof Halasa
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] WAN: fix Cisco HDLC handshaking.
2009-10-09 16:16 [PATCH] WAN: fix Cisco HDLC handshaking Krzysztof Halasa
@ 2009-10-13 10:18 ` David Miller
0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2009-10-13 10:18 UTC (permalink / raw)
To: khc; +Cc: netdev
From: Krzysztof Halasa <khc@pm.waw.pl>
Date: Fri, 09 Oct 2009 18:16:10 +0200
> WAN: fix Cisco HDLC handshaking.
>
> Cisco HDLC uses keepalive packets and sequence numbers to determine link
> state. In rare cases both ends could transmit keepalive packets at the same
> time, causing the received sequence numbers to be treated as incorrect.
> Now we accept our current sequence number as well as the previous one.
>
> Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
Applied, thanks!
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-10-13 10:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-09 16:16 [PATCH] WAN: fix Cisco HDLC handshaking Krzysztof Halasa
2009-10-13 10:18 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).