xref: /kernel/linux/linux-6.6/net/caif/cfpkt_skbuff.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) ST-Ericsson AB 2010
462306a36Sopenharmony_ci * Author:	Sjur Brendeland
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/string.h>
1062306a36Sopenharmony_ci#include <linux/skbuff.h>
1162306a36Sopenharmony_ci#include <linux/export.h>
1262306a36Sopenharmony_ci#include <net/caif/cfpkt.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#define PKT_PREFIX  48
1562306a36Sopenharmony_ci#define PKT_POSTFIX 2
1662306a36Sopenharmony_ci#define PKT_LEN_WHEN_EXTENDING 128
1762306a36Sopenharmony_ci#define PKT_ERROR(pkt, errmsg)		   \
1862306a36Sopenharmony_cido {					   \
1962306a36Sopenharmony_ci	cfpkt_priv(pkt)->erronous = true;  \
2062306a36Sopenharmony_ci	skb_reset_tail_pointer(&pkt->skb); \
2162306a36Sopenharmony_ci	pr_warn(errmsg);		   \
2262306a36Sopenharmony_ci} while (0)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct cfpktq {
2562306a36Sopenharmony_ci	struct sk_buff_head head;
2662306a36Sopenharmony_ci	atomic_t count;
2762306a36Sopenharmony_ci	/* Lock protects count updates */
2862306a36Sopenharmony_ci	spinlock_t lock;
2962306a36Sopenharmony_ci};
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/*
3262306a36Sopenharmony_ci * net/caif/ is generic and does not
3362306a36Sopenharmony_ci * understand SKB, so we do this typecast
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_cistruct cfpkt {
3662306a36Sopenharmony_ci	struct sk_buff skb;
3762306a36Sopenharmony_ci};
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* Private data inside SKB */
4062306a36Sopenharmony_cistruct cfpkt_priv_data {
4162306a36Sopenharmony_ci	struct dev_info dev_info;
4262306a36Sopenharmony_ci	bool erronous;
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic inline struct cfpkt_priv_data *cfpkt_priv(struct cfpkt *pkt)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	return (struct cfpkt_priv_data *) pkt->skb.cb;
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic inline bool is_erronous(struct cfpkt *pkt)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	return cfpkt_priv(pkt)->erronous;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic inline struct sk_buff *pkt_to_skb(struct cfpkt *pkt)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	return &pkt->skb;
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic inline struct cfpkt *skb_to_pkt(struct sk_buff *skb)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	return (struct cfpkt *) skb;
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistruct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	struct cfpkt *pkt = skb_to_pkt(nativepkt);
6862306a36Sopenharmony_ci	cfpkt_priv(pkt)->erronous = false;
6962306a36Sopenharmony_ci	return pkt;
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ciEXPORT_SYMBOL(cfpkt_fromnative);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_civoid *cfpkt_tonative(struct cfpkt *pkt)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	return (void *) pkt;
7662306a36Sopenharmony_ci}
7762306a36Sopenharmony_ciEXPORT_SYMBOL(cfpkt_tonative);
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	struct sk_buff *skb;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	skb = alloc_skb(len + pfx, GFP_ATOMIC);
8462306a36Sopenharmony_ci	if (unlikely(skb == NULL))
8562306a36Sopenharmony_ci		return NULL;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	skb_reserve(skb, pfx);
8862306a36Sopenharmony_ci	return skb_to_pkt(skb);
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciinline struct cfpkt *cfpkt_create(u16 len)
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci	return cfpkt_create_pfx(len + PKT_POSTFIX, PKT_PREFIX);
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_civoid cfpkt_destroy(struct cfpkt *pkt)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
9962306a36Sopenharmony_ci	kfree_skb(skb);
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciinline bool cfpkt_more(struct cfpkt *pkt)
10362306a36Sopenharmony_ci{
10462306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
10562306a36Sopenharmony_ci	return skb->len > 0;
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ciint cfpkt_peek_head(struct cfpkt *pkt, void *data, u16 len)
10962306a36Sopenharmony_ci{
11062306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
11162306a36Sopenharmony_ci	if (skb_headlen(skb) >= len) {
11262306a36Sopenharmony_ci		memcpy(data, skb->data, len);
11362306a36Sopenharmony_ci		return 0;
11462306a36Sopenharmony_ci	}
11562306a36Sopenharmony_ci	return !cfpkt_extr_head(pkt, data, len) &&
11662306a36Sopenharmony_ci	    !cfpkt_add_head(pkt, data, len);
11762306a36Sopenharmony_ci}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciint cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
12262306a36Sopenharmony_ci	u8 *from;
12362306a36Sopenharmony_ci	if (unlikely(is_erronous(pkt)))
12462306a36Sopenharmony_ci		return -EPROTO;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	if (unlikely(len > skb->len)) {
12762306a36Sopenharmony_ci		PKT_ERROR(pkt, "read beyond end of packet\n");
12862306a36Sopenharmony_ci		return -EPROTO;
12962306a36Sopenharmony_ci	}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	if (unlikely(len > skb_headlen(skb))) {
13262306a36Sopenharmony_ci		if (unlikely(skb_linearize(skb) != 0)) {
13362306a36Sopenharmony_ci			PKT_ERROR(pkt, "linearize failed\n");
13462306a36Sopenharmony_ci			return -EPROTO;
13562306a36Sopenharmony_ci		}
13662306a36Sopenharmony_ci	}
13762306a36Sopenharmony_ci	from = skb_pull(skb, len);
13862306a36Sopenharmony_ci	from -= len;
13962306a36Sopenharmony_ci	if (data)
14062306a36Sopenharmony_ci		memcpy(data, from, len);
14162306a36Sopenharmony_ci	return 0;
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ciEXPORT_SYMBOL(cfpkt_extr_head);
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ciint cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len)
14662306a36Sopenharmony_ci{
14762306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
14862306a36Sopenharmony_ci	u8 *data = dta;
14962306a36Sopenharmony_ci	u8 *from;
15062306a36Sopenharmony_ci	if (unlikely(is_erronous(pkt)))
15162306a36Sopenharmony_ci		return -EPROTO;
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	if (unlikely(skb_linearize(skb) != 0)) {
15462306a36Sopenharmony_ci		PKT_ERROR(pkt, "linearize failed\n");
15562306a36Sopenharmony_ci		return -EPROTO;
15662306a36Sopenharmony_ci	}
15762306a36Sopenharmony_ci	if (unlikely(skb->data + len > skb_tail_pointer(skb))) {
15862306a36Sopenharmony_ci		PKT_ERROR(pkt, "read beyond end of packet\n");
15962306a36Sopenharmony_ci		return -EPROTO;
16062306a36Sopenharmony_ci	}
16162306a36Sopenharmony_ci	from = skb_tail_pointer(skb) - len;
16262306a36Sopenharmony_ci	skb_trim(skb, skb->len - len);
16362306a36Sopenharmony_ci	memcpy(data, from, len);
16462306a36Sopenharmony_ci	return 0;
16562306a36Sopenharmony_ci}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ciint cfpkt_pad_trail(struct cfpkt *pkt, u16 len)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	return cfpkt_add_body(pkt, NULL, len);
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ciint cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
17562306a36Sopenharmony_ci	struct sk_buff *lastskb;
17662306a36Sopenharmony_ci	u8 *to;
17762306a36Sopenharmony_ci	u16 addlen = 0;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	if (unlikely(is_erronous(pkt)))
18162306a36Sopenharmony_ci		return -EPROTO;
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	lastskb = skb;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	/* Check whether we need to add space at the tail */
18662306a36Sopenharmony_ci	if (unlikely(skb_tailroom(skb) < len)) {
18762306a36Sopenharmony_ci		if (likely(len < PKT_LEN_WHEN_EXTENDING))
18862306a36Sopenharmony_ci			addlen = PKT_LEN_WHEN_EXTENDING;
18962306a36Sopenharmony_ci		else
19062306a36Sopenharmony_ci			addlen = len;
19162306a36Sopenharmony_ci	}
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	/* Check whether we need to change the SKB before writing to the tail */
19462306a36Sopenharmony_ci	if (unlikely((addlen > 0) || skb_cloned(skb) || skb_shared(skb))) {
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci		/* Make sure data is writable */
19762306a36Sopenharmony_ci		if (unlikely(skb_cow_data(skb, addlen, &lastskb) < 0)) {
19862306a36Sopenharmony_ci			PKT_ERROR(pkt, "cow failed\n");
19962306a36Sopenharmony_ci			return -EPROTO;
20062306a36Sopenharmony_ci		}
20162306a36Sopenharmony_ci	}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	/* All set to put the last SKB and optionally write data there. */
20462306a36Sopenharmony_ci	to = pskb_put(skb, lastskb, len);
20562306a36Sopenharmony_ci	if (likely(data))
20662306a36Sopenharmony_ci		memcpy(to, data, len);
20762306a36Sopenharmony_ci	return 0;
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ciinline int cfpkt_addbdy(struct cfpkt *pkt, u8 data)
21162306a36Sopenharmony_ci{
21262306a36Sopenharmony_ci	return cfpkt_add_body(pkt, &data, 1);
21362306a36Sopenharmony_ci}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ciint cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
21862306a36Sopenharmony_ci	struct sk_buff *lastskb;
21962306a36Sopenharmony_ci	u8 *to;
22062306a36Sopenharmony_ci	const u8 *data = data2;
22162306a36Sopenharmony_ci	int ret;
22262306a36Sopenharmony_ci	if (unlikely(is_erronous(pkt)))
22362306a36Sopenharmony_ci		return -EPROTO;
22462306a36Sopenharmony_ci	if (unlikely(skb_headroom(skb) < len)) {
22562306a36Sopenharmony_ci		PKT_ERROR(pkt, "no headroom\n");
22662306a36Sopenharmony_ci		return -EPROTO;
22762306a36Sopenharmony_ci	}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	/* Make sure data is writable */
23062306a36Sopenharmony_ci	ret = skb_cow_data(skb, 0, &lastskb);
23162306a36Sopenharmony_ci	if (unlikely(ret < 0)) {
23262306a36Sopenharmony_ci		PKT_ERROR(pkt, "cow failed\n");
23362306a36Sopenharmony_ci		return ret;
23462306a36Sopenharmony_ci	}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	to = skb_push(skb, len);
23762306a36Sopenharmony_ci	memcpy(to, data, len);
23862306a36Sopenharmony_ci	return 0;
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ciEXPORT_SYMBOL(cfpkt_add_head);
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ciinline int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len)
24362306a36Sopenharmony_ci{
24462306a36Sopenharmony_ci	return cfpkt_add_body(pkt, data, len);
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ciinline u16 cfpkt_getlen(struct cfpkt *pkt)
24862306a36Sopenharmony_ci{
24962306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
25062306a36Sopenharmony_ci	return skb->len;
25162306a36Sopenharmony_ci}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ciint cfpkt_iterate(struct cfpkt *pkt,
25462306a36Sopenharmony_ci		  u16 (*iter_func)(u16, void *, u16),
25562306a36Sopenharmony_ci		  u16 data)
25662306a36Sopenharmony_ci{
25762306a36Sopenharmony_ci	/*
25862306a36Sopenharmony_ci	 * Don't care about the performance hit of linearizing,
25962306a36Sopenharmony_ci	 * Checksum should not be used on high-speed interfaces anyway.
26062306a36Sopenharmony_ci	 */
26162306a36Sopenharmony_ci	if (unlikely(is_erronous(pkt)))
26262306a36Sopenharmony_ci		return -EPROTO;
26362306a36Sopenharmony_ci	if (unlikely(skb_linearize(&pkt->skb) != 0)) {
26462306a36Sopenharmony_ci		PKT_ERROR(pkt, "linearize failed\n");
26562306a36Sopenharmony_ci		return -EPROTO;
26662306a36Sopenharmony_ci	}
26762306a36Sopenharmony_ci	return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt));
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ciint cfpkt_setlen(struct cfpkt *pkt, u16 len)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	if (unlikely(is_erronous(pkt)))
27662306a36Sopenharmony_ci		return -EPROTO;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	if (likely(len <= skb->len)) {
27962306a36Sopenharmony_ci		if (unlikely(skb->data_len))
28062306a36Sopenharmony_ci			___pskb_trim(skb, len);
28162306a36Sopenharmony_ci		else
28262306a36Sopenharmony_ci			skb_trim(skb, len);
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci		return cfpkt_getlen(pkt);
28562306a36Sopenharmony_ci	}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	/* Need to expand SKB */
28862306a36Sopenharmony_ci	if (unlikely(!cfpkt_pad_trail(pkt, len - skb->len)))
28962306a36Sopenharmony_ci		PKT_ERROR(pkt, "skb_pad_trail failed\n");
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	return cfpkt_getlen(pkt);
29262306a36Sopenharmony_ci}
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cistruct cfpkt *cfpkt_append(struct cfpkt *dstpkt,
29562306a36Sopenharmony_ci			   struct cfpkt *addpkt,
29662306a36Sopenharmony_ci			   u16 expectlen)
29762306a36Sopenharmony_ci{
29862306a36Sopenharmony_ci	struct sk_buff *dst = pkt_to_skb(dstpkt);
29962306a36Sopenharmony_ci	struct sk_buff *add = pkt_to_skb(addpkt);
30062306a36Sopenharmony_ci	u16 addlen = skb_headlen(add);
30162306a36Sopenharmony_ci	u16 neededtailspace;
30262306a36Sopenharmony_ci	struct sk_buff *tmp;
30362306a36Sopenharmony_ci	u16 dstlen;
30462306a36Sopenharmony_ci	u16 createlen;
30562306a36Sopenharmony_ci	if (unlikely(is_erronous(dstpkt) || is_erronous(addpkt))) {
30662306a36Sopenharmony_ci		return dstpkt;
30762306a36Sopenharmony_ci	}
30862306a36Sopenharmony_ci	if (expectlen > addlen)
30962306a36Sopenharmony_ci		neededtailspace = expectlen;
31062306a36Sopenharmony_ci	else
31162306a36Sopenharmony_ci		neededtailspace = addlen;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	if (dst->tail + neededtailspace > dst->end) {
31462306a36Sopenharmony_ci		/* Create a dumplicate of 'dst' with more tail space */
31562306a36Sopenharmony_ci		struct cfpkt *tmppkt;
31662306a36Sopenharmony_ci		dstlen = skb_headlen(dst);
31762306a36Sopenharmony_ci		createlen = dstlen + neededtailspace;
31862306a36Sopenharmony_ci		tmppkt = cfpkt_create(createlen + PKT_PREFIX + PKT_POSTFIX);
31962306a36Sopenharmony_ci		if (tmppkt == NULL)
32062306a36Sopenharmony_ci			return NULL;
32162306a36Sopenharmony_ci		tmp = pkt_to_skb(tmppkt);
32262306a36Sopenharmony_ci		skb_put_data(tmp, dst->data, dstlen);
32362306a36Sopenharmony_ci		cfpkt_destroy(dstpkt);
32462306a36Sopenharmony_ci		dst = tmp;
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci	skb_put_data(dst, add->data, skb_headlen(add));
32762306a36Sopenharmony_ci	cfpkt_destroy(addpkt);
32862306a36Sopenharmony_ci	return skb_to_pkt(dst);
32962306a36Sopenharmony_ci}
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_cistruct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
33262306a36Sopenharmony_ci{
33362306a36Sopenharmony_ci	struct sk_buff *skb2;
33462306a36Sopenharmony_ci	struct sk_buff *skb = pkt_to_skb(pkt);
33562306a36Sopenharmony_ci	struct cfpkt *tmppkt;
33662306a36Sopenharmony_ci	u8 *split = skb->data + pos;
33762306a36Sopenharmony_ci	u16 len2nd = skb_tail_pointer(skb) - split;
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	if (unlikely(is_erronous(pkt)))
34062306a36Sopenharmony_ci		return NULL;
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	if (skb->data + pos > skb_tail_pointer(skb)) {
34362306a36Sopenharmony_ci		PKT_ERROR(pkt, "trying to split beyond end of packet\n");
34462306a36Sopenharmony_ci		return NULL;
34562306a36Sopenharmony_ci	}
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	/* Create a new packet for the second part of the data */
34862306a36Sopenharmony_ci	tmppkt = cfpkt_create_pfx(len2nd + PKT_PREFIX + PKT_POSTFIX,
34962306a36Sopenharmony_ci				  PKT_PREFIX);
35062306a36Sopenharmony_ci	if (tmppkt == NULL)
35162306a36Sopenharmony_ci		return NULL;
35262306a36Sopenharmony_ci	skb2 = pkt_to_skb(tmppkt);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	if (skb2 == NULL)
35662306a36Sopenharmony_ci		return NULL;
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	skb_put_data(skb2, split, len2nd);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	/* Reduce the length of the original packet */
36162306a36Sopenharmony_ci	skb_trim(skb, pos);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	skb2->priority = skb->priority;
36462306a36Sopenharmony_ci	return skb_to_pkt(skb2);
36562306a36Sopenharmony_ci}
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_cibool cfpkt_erroneous(struct cfpkt *pkt)
36862306a36Sopenharmony_ci{
36962306a36Sopenharmony_ci	return cfpkt_priv(pkt)->erronous;
37062306a36Sopenharmony_ci}
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cistruct caif_payload_info *cfpkt_info(struct cfpkt *pkt)
37362306a36Sopenharmony_ci{
37462306a36Sopenharmony_ci	return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb;
37562306a36Sopenharmony_ci}
37662306a36Sopenharmony_ciEXPORT_SYMBOL(cfpkt_info);
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_civoid cfpkt_set_prio(struct cfpkt *pkt, int prio)
37962306a36Sopenharmony_ci{
38062306a36Sopenharmony_ci	pkt_to_skb(pkt)->priority = prio;
38162306a36Sopenharmony_ci}
38262306a36Sopenharmony_ciEXPORT_SYMBOL(cfpkt_set_prio);
383