Commit 9999314e authored by Xie He's avatar Xie He Committed by Khalid Elmously

drivers/net/wan/x25_asy: Fix to make it work

BugLink: https://bugs.launchpad.net/bugs/1889928

[ Upstream commit 8fdcabea ]

This driver is not working because of problems of its receiving code.
This patch fixes it to make it work.

When the driver receives an LAPB frame, it should first pass the frame
to the LAPB module to process. After processing, the LAPB module passes
the data (the packet) back to the driver, the driver should then add a
one-byte pseudo header and pass the data to upper layers.

The changes to the "x25_asy_bump" function and the
"x25_asy_data_indication" function are to correctly implement this
procedure.

Also, the "x25_asy_unesc" function ignores any frame that is shorter
than 3 bytes. However the shortest frames are 2-byte long. So we need
to change it to allow 2-byte frames to pass.

Cc: Eric Dumazet <edumazet@google.com>
Cc: Martin Schiller <ms@dev.tdt.de>
Signed-off-by: default avatarXie He <xie.he.0141@gmail.com>
Reviewed-by: default avatarMartin Schiller <ms@dev.tdt.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 5b6297d6
...@@ -186,7 +186,7 @@ static inline void x25_asy_unlock(struct x25_asy *sl) ...@@ -186,7 +186,7 @@ static inline void x25_asy_unlock(struct x25_asy *sl)
netif_wake_queue(sl->dev); netif_wake_queue(sl->dev);
} }
/* Send one completely decapsulated IP datagram to the IP layer. */ /* Send an LAPB frame to the LAPB module to process. */
static void x25_asy_bump(struct x25_asy *sl) static void x25_asy_bump(struct x25_asy *sl)
{ {
...@@ -198,13 +198,12 @@ static void x25_asy_bump(struct x25_asy *sl) ...@@ -198,13 +198,12 @@ static void x25_asy_bump(struct x25_asy *sl)
count = sl->rcount; count = sl->rcount;
dev->stats.rx_bytes += count; dev->stats.rx_bytes += count;
skb = dev_alloc_skb(count+1); skb = dev_alloc_skb(count);
if (skb == NULL) { if (skb == NULL) {
netdev_warn(sl->dev, "memory squeeze, dropping packet\n"); netdev_warn(sl->dev, "memory squeeze, dropping packet\n");
dev->stats.rx_dropped++; dev->stats.rx_dropped++;
return; return;
} }
skb_push(skb, 1); /* LAPB internal control */
memcpy(skb_put(skb, count), sl->rbuff, count); memcpy(skb_put(skb, count), sl->rbuff, count);
skb->protocol = x25_type_trans(skb, sl->dev); skb->protocol = x25_type_trans(skb, sl->dev);
err = lapb_data_received(skb->dev, skb); err = lapb_data_received(skb->dev, skb);
...@@ -212,7 +211,6 @@ static void x25_asy_bump(struct x25_asy *sl) ...@@ -212,7 +211,6 @@ static void x25_asy_bump(struct x25_asy *sl)
kfree_skb(skb); kfree_skb(skb);
printk(KERN_DEBUG "x25_asy: data received err - %d\n", err); printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
} else { } else {
netif_rx(skb);
dev->stats.rx_packets++; dev->stats.rx_packets++;
} }
} }
...@@ -358,12 +356,21 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb, ...@@ -358,12 +356,21 @@ static netdev_tx_t x25_asy_xmit(struct sk_buff *skb,
*/ */
/* /*
* Called when I frame data arrives. We did the work above - throw it * Called when I frame data arrive. We add a pseudo header for upper
* at the net layer. * layers and pass it to upper layers.
*/ */
static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb) static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
{ {
if (skb_cow(skb, 1)) {
kfree_skb(skb);
return NET_RX_DROP;
}
skb_push(skb, 1);
skb->data[0] = X25_IFACE_DATA;
skb->protocol = x25_type_trans(skb, dev);
return netif_rx(skb); return netif_rx(skb);
} }
...@@ -655,7 +662,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char s) ...@@ -655,7 +662,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
switch (s) { switch (s) {
case X25_END: case X25_END:
if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
sl->rcount > 2) sl->rcount >= 2)
x25_asy_bump(sl); x25_asy_bump(sl);
clear_bit(SLF_ESCAPE, &sl->flags); clear_bit(SLF_ESCAPE, &sl->flags);
sl->rcount = 0; sl->rcount = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment