Commit ba0c5354 authored by David S. Miller's avatar David S. Miller

[LAPB]: Fix packet handlers to be PKT_CAN_SHARE_SKB.

parent 72570ff1
...@@ -372,6 +372,10 @@ static int comxlapb_data_indication(void *token, struct sk_buff *skb) ...@@ -372,6 +372,10 @@ static int comxlapb_data_indication(void *token, struct sk_buff *skb)
if (ch->dev->type == ARPHRD_X25) { if (ch->dev->type == ARPHRD_X25) {
skb_push(skb, 1); skb_push(skb, 1);
if (skb_cow(skb, 1))
return NET_RX_DROP;
skb->data[0] = 0; // indicate data for X25 skb->data[0] = 0; // indicate data for X25
skb->protocol = htons(ETH_P_X25); skb->protocol = htons(ETH_P_X25);
} else { } else {
......
...@@ -68,7 +68,12 @@ static int x25_data_indication(void *token, struct sk_buff *skb) ...@@ -68,7 +68,12 @@ static int x25_data_indication(void *token, struct sk_buff *skb)
hdlc_device *hdlc = token; hdlc_device *hdlc = token;
unsigned char *ptr; unsigned char *ptr;
ptr = skb_push(skb, 1); skb_push(skb, 1);
if (skb_cow(skb, 1))
return NET_RX_DROP;
ptr = skb->data;
*ptr = 0; *ptr = 0;
skb->dev = hdlc_to_dev(hdlc); skb->dev = hdlc_to_dev(hdlc);
......
...@@ -89,14 +89,15 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe ...@@ -89,14 +89,15 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
int len, err; int len, err;
struct lapbethdev *lapbeth; struct lapbethdev *lapbeth;
skb->sk = NULL; /* Initially we don't know who it's for */ if (!pskb_may_pull(skb, 2))
goto drop;
rcu_read_lock(); rcu_read_lock();
lapbeth = lapbeth_get_x25_dev(dev); lapbeth = lapbeth_get_x25_dev(dev);
if (!lapbeth) if (!lapbeth)
goto drop; goto drop_unlock;
if (!netif_running(lapbeth->axdev)) if (!netif_running(lapbeth->axdev))
goto drop; goto drop_unlock;
lapbeth->stats.rx_packets++; lapbeth->stats.rx_packets++;
...@@ -108,14 +109,17 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe ...@@ -108,14 +109,17 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
if ((err = lapb_data_received(lapbeth, skb)) != LAPB_OK) { if ((err = lapb_data_received(lapbeth, skb)) != LAPB_OK) {
printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err); printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err);
goto drop; goto drop_unlock;
} }
out: out:
rcu_read_unlock(); rcu_read_unlock();
return 0; return 0;
drop: drop_unlock:
kfree_skb(skb); kfree_skb(skb);
goto out; goto out;
drop:
kfree_skb(skb);
return 0;
} }
static int lapbeth_data_indication(void *token, struct sk_buff *skb) static int lapbeth_data_indication(void *token, struct sk_buff *skb)
...@@ -123,7 +127,12 @@ static int lapbeth_data_indication(void *token, struct sk_buff *skb) ...@@ -123,7 +127,12 @@ static int lapbeth_data_indication(void *token, struct sk_buff *skb)
struct lapbethdev *lapbeth = (struct lapbethdev *)token; struct lapbethdev *lapbeth = (struct lapbethdev *)token;
unsigned char *ptr; unsigned char *ptr;
ptr = skb_push(skb, 1); skb_push(skb, 1);
if (skb_cow(skb, 1))
return NET_RX_DROP;
ptr = skb->data;
*ptr = 0x00; *ptr = 0x00;
skb->dev = lapbeth->axdev; skb->dev = lapbeth->axdev;
...@@ -426,6 +435,7 @@ static int lapbeth_device_event(struct notifier_block *this, ...@@ -426,6 +435,7 @@ static int lapbeth_device_event(struct notifier_block *this,
static struct packet_type lapbeth_packet_type = { static struct packet_type lapbeth_packet_type = {
.type = __constant_htons(ETH_P_DEC), .type = __constant_htons(ETH_P_DEC),
.func = lapbeth_rcv, .func = lapbeth_rcv,
.data = PKT_CAN_SHARE_SKB,
}; };
static struct notifier_block lapbeth_dev_notifier = { static struct notifier_block lapbeth_dev_notifier = {
......
...@@ -129,7 +129,7 @@ extern void lapb_clear_queues(struct lapb_cb *lapb); ...@@ -129,7 +129,7 @@ extern void lapb_clear_queues(struct lapb_cb *lapb);
extern void lapb_frames_acked(struct lapb_cb *lapb, unsigned short); extern void lapb_frames_acked(struct lapb_cb *lapb, unsigned short);
extern void lapb_requeue_frames(struct lapb_cb *lapb); extern void lapb_requeue_frames(struct lapb_cb *lapb);
extern int lapb_validate_nr(struct lapb_cb *lapb, unsigned short); extern int lapb_validate_nr(struct lapb_cb *lapb, unsigned short);
extern void lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *); extern int lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *);
extern void lapb_send_control(struct lapb_cb *lapb, int, int, int); extern void lapb_send_control(struct lapb_cb *lapb, int, int, int);
extern void lapb_transmit_frmr(struct lapb_cb *lapb); extern void lapb_transmit_frmr(struct lapb_cb *lapb);
......
...@@ -702,7 +702,10 @@ void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb) ...@@ -702,7 +702,10 @@ void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
{ {
struct lapb_frame frame; struct lapb_frame frame;
lapb_decode(lapb, skb, &frame); if (lapb_decode(lapb, skb, &frame) < 0) {
kfree_skb(skb);
return;
}
switch (lapb->state) { switch (lapb->state) {
case LAPB_STATE_0: case LAPB_STATE_0:
......
...@@ -107,8 +107,8 @@ int lapb_validate_nr(struct lapb_cb *lapb, unsigned short nr) ...@@ -107,8 +107,8 @@ int lapb_validate_nr(struct lapb_cb *lapb, unsigned short nr)
* This routine is the centralised routine for parsing the control * This routine is the centralised routine for parsing the control
* information for the different frame formats. * information for the different frame formats.
*/ */
void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb, int lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
struct lapb_frame *frame) struct lapb_frame *frame)
{ {
frame->type = LAPB_ILLEGAL; frame->type = LAPB_ILLEGAL;
...@@ -118,6 +118,12 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb, ...@@ -118,6 +118,12 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
skb->data[0], skb->data[1], skb->data[2]); skb->data[0], skb->data[1], skb->data[2]);
#endif #endif
/* We always need to look at 2 bytes, sometimes we need
* to look at 3 and those cases are handled below.
*/
if (!pskb_may_pull(skb, 2))
return -1;
if (lapb->mode & LAPB_MLP) { if (lapb->mode & LAPB_MLP) {
if (lapb->mode & LAPB_DCE) { if (lapb->mode & LAPB_DCE) {
if (skb->data[0] == LAPB_ADDR_D) if (skb->data[0] == LAPB_ADDR_D)
...@@ -148,6 +154,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb, ...@@ -148,6 +154,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
if (lapb->mode & LAPB_EXTENDED) { if (lapb->mode & LAPB_EXTENDED) {
if (!(skb->data[0] & LAPB_S)) { if (!(skb->data[0] & LAPB_S)) {
if (!pskb_may_pull(skb, 2))
return -1;
/* /*
* I frame - carries NR/NS/PF * I frame - carries NR/NS/PF
*/ */
...@@ -159,6 +167,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb, ...@@ -159,6 +167,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
frame->control[1] = skb->data[1]; frame->control[1] = skb->data[1];
skb_pull(skb, 2); skb_pull(skb, 2);
} else if ((skb->data[0] & LAPB_U) == 1) { } else if ((skb->data[0] & LAPB_U) == 1) {
if (!pskb_may_pull(skb, 2))
return -1;
/* /*
* S frame - take out PF/NR * S frame - take out PF/NR
*/ */
...@@ -206,6 +216,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb, ...@@ -206,6 +216,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
skb_pull(skb, 1); skb_pull(skb, 1);
} }
return 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