162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2008, Intel Corporation.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Author: Alexander Duyck <alexander.h.duyck@intel.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef __NET_TC_SKBEDIT_H
962306a36Sopenharmony_ci#define __NET_TC_SKBEDIT_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <net/act_api.h>
1262306a36Sopenharmony_ci#include <linux/tc_act/tc_skbedit.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistruct tcf_skbedit_params {
1562306a36Sopenharmony_ci	u32 flags;
1662306a36Sopenharmony_ci	u32 priority;
1762306a36Sopenharmony_ci	u32 mark;
1862306a36Sopenharmony_ci	u32 mask;
1962306a36Sopenharmony_ci	u16 queue_mapping;
2062306a36Sopenharmony_ci	u16 mapping_mod;
2162306a36Sopenharmony_ci	u16 ptype;
2262306a36Sopenharmony_ci	struct rcu_head rcu;
2362306a36Sopenharmony_ci};
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistruct tcf_skbedit {
2662306a36Sopenharmony_ci	struct tc_action common;
2762306a36Sopenharmony_ci	struct tcf_skbedit_params __rcu *params;
2862306a36Sopenharmony_ci};
2962306a36Sopenharmony_ci#define to_skbedit(a) ((struct tcf_skbedit *)a)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/* Return true iff action is the one identified by FLAG. */
3262306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_with_flag(const struct tc_action *a, u32 flag)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci#ifdef CONFIG_NET_CLS_ACT
3562306a36Sopenharmony_ci	u32 flags;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	if (a->ops && a->ops->id == TCA_ID_SKBEDIT) {
3862306a36Sopenharmony_ci		rcu_read_lock();
3962306a36Sopenharmony_ci		flags = rcu_dereference(to_skbedit(a)->params)->flags;
4062306a36Sopenharmony_ci		rcu_read_unlock();
4162306a36Sopenharmony_ci		return flags == flag;
4262306a36Sopenharmony_ci	}
4362306a36Sopenharmony_ci#endif
4462306a36Sopenharmony_ci	return false;
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/* Return true iff action is mark */
4862306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_mark(const struct tc_action *a)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	return is_tcf_skbedit_with_flag(a, SKBEDIT_F_MARK);
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline u32 tcf_skbedit_mark(const struct tc_action *a)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	u32 mark;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	rcu_read_lock();
5862306a36Sopenharmony_ci	mark = rcu_dereference(to_skbedit(a)->params)->mark;
5962306a36Sopenharmony_ci	rcu_read_unlock();
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	return mark;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/* Return true iff action is ptype */
6562306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_ptype(const struct tc_action *a)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	return is_tcf_skbedit_with_flag(a, SKBEDIT_F_PTYPE);
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic inline u32 tcf_skbedit_ptype(const struct tc_action *a)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	u16 ptype;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	rcu_read_lock();
7562306a36Sopenharmony_ci	ptype = rcu_dereference(to_skbedit(a)->params)->ptype;
7662306a36Sopenharmony_ci	rcu_read_unlock();
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	return ptype;
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/* Return true iff action is priority */
8262306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_priority(const struct tc_action *a)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	return is_tcf_skbedit_with_flag(a, SKBEDIT_F_PRIORITY);
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic inline u32 tcf_skbedit_priority(const struct tc_action *a)
8862306a36Sopenharmony_ci{
8962306a36Sopenharmony_ci	u32 priority;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	rcu_read_lock();
9262306a36Sopenharmony_ci	priority = rcu_dereference(to_skbedit(a)->params)->priority;
9362306a36Sopenharmony_ci	rcu_read_unlock();
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	return priority;
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic inline u16 tcf_skbedit_rx_queue_mapping(const struct tc_action *a)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	u16 rx_queue;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	rcu_read_lock();
10362306a36Sopenharmony_ci	rx_queue = rcu_dereference(to_skbedit(a)->params)->queue_mapping;
10462306a36Sopenharmony_ci	rcu_read_unlock();
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	return rx_queue;
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/* Return true iff action is queue_mapping */
11062306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_queue_mapping(const struct tc_action *a)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	return is_tcf_skbedit_with_flag(a, SKBEDIT_F_QUEUE_MAPPING);
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/* Return true if action is on ingress traffic */
11662306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_ingress(u32 flags)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	return flags & TCA_ACT_FLAGS_AT_INGRESS;
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_tx_queue_mapping(const struct tc_action *a)
12262306a36Sopenharmony_ci{
12362306a36Sopenharmony_ci	return is_tcf_skbedit_queue_mapping(a) &&
12462306a36Sopenharmony_ci	       !is_tcf_skbedit_ingress(a->tcfa_flags);
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_rx_queue_mapping(const struct tc_action *a)
12862306a36Sopenharmony_ci{
12962306a36Sopenharmony_ci	return is_tcf_skbedit_queue_mapping(a) &&
13062306a36Sopenharmony_ci	       is_tcf_skbedit_ingress(a->tcfa_flags);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci/* Return true iff action is inheritdsfield */
13462306a36Sopenharmony_cistatic inline bool is_tcf_skbedit_inheritdsfield(const struct tc_action *a)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	return is_tcf_skbedit_with_flag(a, SKBEDIT_F_INHERITDSFIELD);
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#endif /* __NET_TC_SKBEDIT_H */
140