コード例 #1
0
ファイル: cfpkt_skbuff.c プロジェクト: Anjali05/linux
struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
{
	struct sk_buff *skb2;
	struct sk_buff *skb = pkt_to_skb(pkt);
	struct cfpkt *tmppkt;
	u8 *split = skb->data + pos;
	u16 len2nd = skb_tail_pointer(skb) - split;

	if (unlikely(is_erronous(pkt)))
		return NULL;

	if (skb->data + pos > skb_tail_pointer(skb)) {
		PKT_ERROR(pkt, "trying to split beyond end of packet\n");
		return NULL;
	}

	/* Create a new packet for the second part of the data */
	tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
				  PKT_PREFIX);
	if (tmppkt == NULL)
		return NULL;
	skb2 = pkt_to_skb(tmppkt);


	if (skb2 == NULL)
		return NULL;

	skb_put_data(skb2, split, len2nd);

	/* Reduce the length of the original packet */
	skb_trim(skb, pos);

	skb2->priority = skb->priority;
	return skb_to_pkt(skb2);
}
コード例 #2
0
struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq)
{
	struct cfpkt *tmp;
	spin_lock(&pktq->lock);
	tmp = skb_to_pkt(skb_peek(&pktq->head));
	spin_unlock(&pktq->lock);
	return tmp;
}
コード例 #3
0
struct cfpkt *cfpkt_clone_release(struct cfpkt *pkt)
{
	struct cfpkt *clone;
	clone  = skb_to_pkt(skb_clone(pkt_to_skb(pkt), GFP_ATOMIC));
	/* Free original packet. */
	cfpkt_destroy(pkt);
	if (!clone)
		return NULL;
	return clone;
}
コード例 #4
0
ファイル: cfpkt_skbuff.c プロジェクト: AlexShiLucky/linux
static struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx)
{
	struct sk_buff *skb;

	skb = alloc_skb(len + pfx, GFP_ATOMIC);
	if (unlikely(skb == NULL))
		return NULL;

	skb_reserve(skb, pfx);
	return skb_to_pkt(skb);
}
コード例 #5
0
struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq)
{
	struct cfpkt *pkt;
	spin_lock(&pktq->lock);
	pkt = skb_to_pkt(skb_dequeue(&pktq->head));
	if (pkt) {
		atomic_dec(&pktq->count);
		caif_assert(atomic_read(&pktq->count) >= 0);
	}
	spin_unlock(&pktq->lock);
	return pkt;
}
コード例 #6
0
struct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
			     struct cfpkt *addpkt,
			     u16 expectlen)
{
	struct sk_buff *dst = pkt_to_skb(dstpkt);
	struct sk_buff *add = pkt_to_skb(addpkt);
	u16 addlen = skb_headlen(add);
	u16 neededtailspace;
	struct sk_buff *tmp;
	u16 dstlen;
	u16 createlen;
	if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) {
		cfpkt_destroy(addpkt);
		return dstpkt;
	}
	if (expectlen > addlen)
		neededtailspace = expectlen;
	else
		neededtailspace = addlen;

	if (dst->tail + neededtailspace > dst->end) {
		/* Create a dumplicate of 'dst' with more tail space */
		struct cfpkt *tmppkt;
		dstlen = skb_headlen(dst);
		createlen = dstlen + neededtailspace;
		tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX);
		if (tmppkt == NULL)
			return NULL;
		tmp = pkt_to_skb(tmppkt);
		skb_set_tail_pointer(tmp, dstlen);
		tmp->len = dstlen;
		memcpy(tmp->data, dst->data, dstlen);
		cfpkt_destroy(dstpkt);
		dst = tmp;
	}
	memcpy(skb_tail_pointer(dst), add->data, skb_headlen(add));
	cfpkt_destroy(addpkt);
	dst->tail += addlen;
	dst->len += addlen;
	return skb_to_pkt(dst);
}
コード例 #7
0
ファイル: cfpkt_skbuff.c プロジェクト: AlexShiLucky/linux
struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt)
{
	struct cfpkt *pkt = skb_to_pkt(nativepkt);
	cfpkt_priv(pkt)->erronous = false;
	return pkt;
}