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)
if (ch->dev->type == ARPHRD_X25) {
skb_push(skb, 1);
if (skb_cow(skb, 1))
return NET_RX_DROP;
skb->data[0] = 0; // indicate data for X25
skb->protocol = htons(ETH_P_X25);
} else {
......
......@@ -68,7 +68,12 @@ static int x25_data_indication(void *token, struct sk_buff *skb)
hdlc_device *hdlc = token;
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;
skb->dev = hdlc_to_dev(hdlc);
......
......@@ -89,14 +89,15 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
int len, err;
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();
lapbeth = lapbeth_get_x25_dev(dev);
if (!lapbeth)
goto drop;
goto drop_unlock;
if (!netif_running(lapbeth->axdev))
goto drop;
goto drop_unlock;
lapbeth->stats.rx_packets++;
......@@ -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) {
printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err);
goto drop;
goto drop_unlock;
}
out:
rcu_read_unlock();
return 0;
drop:
drop_unlock:
kfree_skb(skb);
goto out;
drop:
kfree_skb(skb);
return 0;
}
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;
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;
skb->dev = lapbeth->axdev;
......@@ -426,6 +435,7 @@ static int lapbeth_device_event(struct notifier_block *this,
static struct packet_type lapbeth_packet_type = {
.type = __constant_htons(ETH_P_DEC),
.func = lapbeth_rcv,
.data = PKT_CAN_SHARE_SKB,
};
static struct notifier_block lapbeth_dev_notifier = {
......
......@@ -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_requeue_frames(struct lapb_cb *lapb);
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_transmit_frmr(struct lapb_cb *lapb);
......
......@@ -702,7 +702,10 @@ void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
{
struct lapb_frame frame;
lapb_decode(lapb, skb, &frame);
if (lapb_decode(lapb, skb, &frame) < 0) {
kfree_skb(skb);
return;
}
switch (lapb->state) {
case LAPB_STATE_0:
......
......@@ -107,7 +107,7 @@ int lapb_validate_nr(struct lapb_cb *lapb, unsigned short nr)
* This routine is the centralised routine for parsing the control
* 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)
{
frame->type = LAPB_ILLEGAL;
......@@ -118,6 +118,12 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
skb->data[0], skb->data[1], skb->data[2]);
#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_DCE) {
if (skb->data[0] == LAPB_ADDR_D)
......@@ -148,6 +154,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
if (lapb->mode & LAPB_EXTENDED) {
if (!(skb->data[0] & LAPB_S)) {
if (!pskb_may_pull(skb, 2))
return -1;
/*
* I frame - carries NR/NS/PF
*/
......@@ -159,6 +167,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
frame->control[1] = skb->data[1];
skb_pull(skb, 2);
} else if ((skb->data[0] & LAPB_U) == 1) {
if (!pskb_may_pull(skb, 2))
return -1;
/*
* S frame - take out PF/NR
*/
......@@ -206,6 +216,8 @@ void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
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